メイン

Office X アーカイブ

2008年04月14日

サイボウズ Office X 始動

サイボウズ・ラボの畑と申します。

こちらのブログで次世代のサイボウズ Office の開発日記を書くことになりました。サイボウズ・ラボでは、そんなこともやってます。

現在のサイボウズ Office のバージョンが7なので、ここで言う次世代に相当するものが8になるのか9になるのかは、今のところ未定です。次世代とは大げさな言い方かもしれませんが、次期 or 次々期メジャーバージョンアップ版のサイボウズ Office ということになります。ここでは Office X と呼ぶことにします。

で、Office X の大まかな方針として、以下の項目があります。

  • データベースとしてMySQLを採用
  • Unicode対応(ハングルや中文のメールへの対応)

「え、それだけ」と思うかもしれませんが、現在のサイボウズ Office との違いで、最も大きいところはここになるでしょう。すでに、大規模(エンタープライズ)向けのグループウエアであるサイボウズ ガルーンでは、MySQLを採用しUnicode対応していますが、Office X でもその方向に持って行きます。

グループウエアのデータを保存するデータベース部分は、全体の中で非常に大きなウェイトを占めます。よって、システム全体をMySQLを前提とした設計に再構築する必要があります。では、ガルーンのサブセットなりをサイボウズ Office にすれば、と言う話も出てきますが、それについて次回以降で説明したいと思います。

2008年04月16日

C++ で開発

畑です。

標題で結論を言ってしまいましたが、サイボウズ Office X の開発言語は C++ にすることにしました。今までのサイボウズ Office も C++ と独自のテンプレートエンジンで開発しており、その路線を踏襲することになります。

サイボウズ Office はCGIという仕組みで実装したWebアプリケーションですが、Webアプリケーションというと Perl, PHP, Python, Ruby といった軽量プログラミング言語で開発するものというイメージが強いかもしれません。実際、エンタープライズ向けにサイボウズが提供しているサイボウズ ガルーン 2 では開発言語として PHP を選択しました。では、なぜ Office X では C++ にしたかということです。

サイボウズ Office シリーズは今年で11年目になりますが、今度開発する Office X の開発フレームワークも10年ぐらいの寿命を持たせる必要があります。10年ぐらいのスパンで見ると PHP を選択した場合、何回かの言語自体のメジャーバージョンアップが予想され、PHP の旧バージョンのメンテナンス自体が保証されないというリスクも考慮する必要がでてきます。ソースコードが公開されているので自分達でメンテナンスするという方法も取れますが、その分コストがかかることになります。開発言語は開発する製品やサービスのソースコードの寿命を鑑みて選択すれば良い話なので、何も言語仕様が変更されることが悪いと言っているわけではありません。以上のような背景より、サイボウズ Office X の場合は後方互換性という点を重視して C++ を選択するという判断をしました。

また、C++ で開発する理由として高速化の観点もあります。パッケージソフトウェアの場合、ネット上のサービスと異なり、お客様のマシン環境で動作させることになります。高スペックのマシンで動作させる場合もあれば、そうでない場合もあります。つまり開発者側で選択することはできないので、低スペックのマシンでもなるべく動作するように開発する必要があります。インタプリタ言語で開発する場合、速度が求められる部分は後から C++ で実装して拡張モジュールとして呼び出そう、というようなアプローチが取られることもあるかと思います。しかし開発の現場として実際問題として後から C++ 化されずに、ずるずると高速化されないということが起こりうる可能性もあります。マネジメントの問題と言ってしまえばその通りなのですが、この「後から」問題を解決するべく「最初から」手法を導入するのも一案ではないでしょうか。

C++ にすることでメモリの確保に対するケアや、言語習得コストなど、それはそれで軽量プログラミング言語に対するデメリットも多々あります。しかしそれは結局のところ、どこにコストをかけて、どこのコストを削るかという割り切りの問題でしょう。どこのリスクを取って、どこのリスクを取らないか。いずれにせよ何かしらのリスクは取らなければならないのです。

あと、サイボウズ Office X では開発フレームワークから再設計するのですが、C++ で開発することにより、デバッグ済みの従来のサイボウズ Office シリーズのソースコードも活用できる部分がでてきます。

というわけで、今回の話をまとめると、開発言語として C++ を選択する理由は以下の通りです。

  • 言語仕様の後方互換性
  • 言語選択レベルでの高速化が不要
  • 過去の資産の活用

2008年04月17日

ハイブリッド・コンバーター

畑です。

バージョンアップに伴いデータの保存形式が変更されると、必ず必要となってくるのがデータコンバーターです。サイボウズ Office シリーズでも過去バージョン2から3にアップするときに、保存形式が大幅に変更され、データコンバーターを提供していたと記憶しています。また、サイボウズ Office シリーズからサイボウズ ガルーンへの乗り換えに際しても、データコンバーターが必要になっていました。サイボウズ Office X についても、現行バージョンからはデータの保存形式が変更される(MySQLに保存することになる)ので、データの変換が必要となるでしょう。

通常データコンバーターによるデータの変換は、蓄積されているデータが多い場合には時間がかかることがしばしばあります。1回行ってしまえば済むことではありますが、面倒であることには違いありませんし、バージョンアップを躊躇する理由にもなります。

そこでサイボウズ Office X では次のようなデータコンバート機能を目指すことにしました。バージョンアップした時点では、設定等など一瞬で終了する部分や使い始めにあたってどうしても必要な部分のみのデータコンバートを行い、過去のデータについては参照された時点でオンデマンドでデータコンバートを行う、またはバックグランドで徐々にデータコンバートを行うというものです。さらには、コンバートする必要性がないものについては、従来の保存形式のままデータを取り出すことも考えています。その名もハイブリッド・コンバーター(ちょっと言いすぎかな)と呼びましょうか。運用管理者にデータコンバート作業を意識させない形態を目指したいと思います。

2008年04月18日

テンプレートエンジン

畑です。

サイボウズ Office シリーズが C++ と独自のテンプレートエンジンで開発されてきたことは、以前説明しましたがサイボウズ Office X でも、その構成を取る予定です。従来の独自のテンプレートエンジンはデータ保存形式と密に連携していました。しかし、今回 MySQL にデータ保存を委ねることになったので、従来のものを利用するメリットがあまりなくなりました。そこでテンプレートエンジンも一新することになりました。

テンプレートエンジンというと記述形式が非常に重要となります。重要というか、どちらかというと非常に気になるという表現が、使う側にとっては適切かもしれません。例えば変数に格納された値を表示する際には、以下のような記述パターンが各種のテンプレートエンジンで見受けられると思います。

 1. <% $foo %>
 2. [[$foo]]
 3. {$foo}

変数の前後に括弧等がたくさん付くと、記述する際のストレスが溜まるが、HTMLエディタとの親和性は高まる、といったようにそれぞれ特徴があるかと思います。PHP の Smarty は 3 の {$foo} のパターンに相当しますが、変数の前後の括弧が少ないことも人気の理由の1つではないでしょうか。実は、サイボウズ Office シリーズの従来のテンプレートエンジンでは括弧さえない $foo という形式でした。

サイボウズ Office X の開発にあたって、テンプレートエンジンについて考えていることとして「テンプレートファイルは必要最小限の機能に止める」ということがあります。実は従来の Office ではテンプレートに各種のビジネスロジックが混在していたのですが、テンプレートからデータベースを簡単に操作できるといった高度な機能がそれを後押ししてしまった、という反省があるのです。

ここで開発する開発フレームワークはあくまでも社内向けなので、Webアプリケーション開発用といっても、対象とするアプリケーションの機能性については限定することができますし、使用する開発者も限定することができます。したがって「汎用性」ではなく「どのように開発して欲しいか」という観点から、テンプレートエンジン等の機能を設計できます。

まとめますと、テンプレートエンジンを独立した汎用のものとするのではなく、「こうあるべし」と制約するフレームワークの一部とみなして設計・開発していこうと思います。

2008年04月21日

サイボウズ Office X の X はバージョン番号ではありません。

畑です。

サイボウズ Office シリーズの現在のバージョンは7ですが、おそらく次期バージョンは8、次々期バージョンは9になると思います。Max OS X のように、バージョン番号が X になることはないと思います。(サイボウズ Office シリーズは途中 AG という名称の時期もあったので、絶対にないとは言い切れませんが。ちなみにその時期は「サイボウズ AG」という名称で「Office」という単語さえ抜けていました。)サイボウズ Office X は概念的に「次期」「次々期」ぐらいを指すものだと考えて頂ければと思います。つまり、Office 8 がリリースした後には 9 か 10 ぐらいを指している、というような。

ちなみに英語で X という表現は日本語言うところの「某(なにがし)」に相当するということを誰かに聞いたことがあります(間違っていたらごめんなさい)。サイボウズ Office 某。。。うーん、響きから受ける印象が何か違うような気がする。また X という表現はマイクロソフトが好んで使用するワードでもあります。古い例ですと MSX (MicroSoft X) という8ビットパソコンの規格があります。少し最近だと ActiveX、DirectX、ゲーム機に目を移すと XBox。他に何か有名なものはあるかな。

2008年04月23日

最近知った C のマクロ機能

畑です。

恥ずかしながら最近知った C の マクロ機能において、例えば foo という識別子を "foo" という文字列リテラルに変換できることを知りました。これは結構便利です。Webアプリケーションの場合だと、URLの引数をもとに、起動するアクションを振り分けるようなことが、よく見受けられます。そのような時にこの機能が役に立ちます。
void SampleAction::dispatch(const std::string& strName)
{
    if (strName == "list") {list();return}
    if (strName == "add") {add();return}
    if (strName == "view") {view();return}
    if (strName == "modify") {modify();return}
    if (strName == "delete") {delete();return}
}
上記のようなコードを実装したとき、以下のように書くことができ、見た目に非常にスッキリします。
下の例の、#name というのがその機能です。
#define action(name) if (strName == #name) {name();return;}

void SampleAction::dispatch(const std::string& strName)
{
    action(list)
    action(add)
    action(view)
    action(modify)
    action(delete)
}

2008年04月24日

サイボウズ・ラボではいま空前のC++ブーム

畑です。

ここ数年はPHPをよく使っていたのですが、サイボウズ Office X の開発を開始するにあたって再び C++ にどっぷりつかることになりました。タイミングが偶然重なったのかもしれませんが、サイボウズ・ラボではいま空前のC++ブームが起こっています。

C++ テンプレートを使って高速な高機能サーバを書く方法

「C++ のメンバ関数ポインタって何のためにあるの」という質問を耳にすることがあります。実際は、たとえばステートマシンを書くのに便利なのですが、ちょうどサイボウズ・ラボの C++ 熱が盛り上がっていることもあり、昔の作ったサーバフレームワークを再実装してみました。...

「Jythonプログラミング」という本を執筆した西尾さんにいたっては、C++の勉強をするために TopCorder というオンラインで参加できるプログラミングコンテストに参加する勢いです。

Visual C++ のことを高機能なマクロアセンブラだと思っている節がある光成さんからは、C++に関する面白いトピックが載っているサイト(http://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms)を今日教えてもらいました。

で、サイボウズ Office X の開発の進み具合ですが、セッション管理、ユーザー認証まわりを実装して、ログイン・ログアウトができるようになったという段階です。CGIとして動作する基本的な部分については主に既存のサイボウズ Office 7 までのコードを活用しています。

2008年04月25日

MySQL の C API にまつわる悩み

畑です。

MySQL の C API を使うと、カラムのデータ型が INT 型であろうと、VARCHAR 型であろうと、全て文字列として値が返ってきます。文字列で返ってくるというのは、char 型のポインタで返ってくるという意味なのですが、NULL 値の場合は NULL が返ってきます。

さて、ここで考えないといけないのが MySQL の C API を通じて取得した値を C++ 側でどのようなデータ型で格納するかという問題です。インタプリタ言語の場合は異なるデータ型を同じ配列やハッシュ(連想配列)に格納することができるので、INT 型であれば数値型に、VARCHAR 型であれば文字列型に、というふうに変換して適切なデータ型に格納することが多いと思います。しかし C++ では異なるデータ型を同じ配列やハッシュに格納することはできません。そこで、レコード値を格納するために、以下の2通りの方法を考えました。

  1. variant型(何でも型)を定義して、variant型の配列、またはハッシュにレコード値を格納する。
  2. カラムのデータ型が何であろうと、C++側では全て文字列型のまま配列、またはハッシュに格納する。
    必要に応じて long 型等に変換して使用する。
それぞれいろんな長所・短所がありますが、簡単にまとめると以下のような感じでしょうか。
  1. variant型(何でも型)
    長所
    インタプリタ言語のように何でも格納できる。
    短所
    variant型を使うたびに型検査する必要がある。
  2. 全て文字列型
    長所
    シンプル。
    API から取得して格納する際に変換が不要。
    短所
    使用時に数値への変換等が多く発生する。
    文字列 "0" の真偽に悩む。つまり、カラムの型をどこかに記録しておく必要がある。
    NULL値の格納に悩む。
実際にそれぞれの方法でコーディングした場合の例は以下のようになります。
  1. variant型(何でも型)

    map row = db.Row(strSQL);
    cout << row["name"].toString() << ", " << row["age"].toLong();
    long nAge = row["age"].toLong(); // キャスト演算子をオーバーロードすると、toLong() は省ける
  2. 全て文字列型

    map row = db.Row(strSQL);
    cout << row["name"] << ", " << row["age"];
    long nAge = atol(row["age"].c_str());
また、MySQL において BIGINT 型を使用した場合、C++ において整数型で処理する場面では、long long で受ける必要が出てくるところが、また悩ましい。「レコードのID値は64bit必要そうだが、それ以外の整数は32bitあれば十分だしなあ」とか。

で、どうするかなのですが、外部キー制約などで ON DElETE SET NULL のようなことをすることが避けられないので、NULL値の扱いという観点からも 1 の variant型を定義する方向で考えています。最初は 1 しか考えていなかったのですが、実装を進めるうちに 1 の方法のデメリットが見えてきて、「ちょっとまてよ。全部文字列で格納したら何か問題あるか?」と考えるようになりました。すると今度は 2 の方法のデメリットが見えてきて「やっぱり 1 か」となったわけです。

続きを読む "MySQL の C API にまつわる悩み" »

2008年04月30日

MySQL C API の「準備されたC APIステートメント」

畑です。

前回の記事「MySQL の C API にまつわる悩み」において

MySQL の C API を使うと、カラムのデータ型が INT 型であろうと、VARCHAR 型であろうと、全て文字列として値が返ってきます。文字列で返ってくるというのは、char 型のポインタで返ってくるという意味なのですが、NULL 値の場合は NULL が返ってきます。
と申しておりましたが、表現が正確ではありませんでした。

MySQL の C API のうち、mysql_fetch_row() を使った場合は、前回の記事のとおり、全て文字列として値が返ってくるのですが、MySQL 4.1 以降ではプリペアドステートメント用の C API を使用することで、カラムのデータ型に合った C のデータ型としてデータを受信することができます。このプリペアードステートメント用の C API は関数名は mysql_stmt_ で始まります

ちなみにこのプリペアードステートメントについて、MySQL 4.1 の日本語マニュアルでは「C API のプリペアードステートメント」というタイトルになっているのですが、MySQL 5.1 の日本語マニュアルでは「準備されたC APIステートメント」となっており直訳されておりました。

2008年05月07日

Web 上で C++ のコードをテストする方法

畑です。

C++ はコンパイル言語なので、テストする場合コンパイル&ビルドして実行形式に直してから実行させてみる必要があります。しかし、ちょっとしたコードの断片なんかを「このコードで合っているかなあ?」と思ってテストしたいとき、いちいち1つの実行形式を作るのが面倒な場合があります。boost::unit_test_framework なんかを使えば、比較的楽にテストできますが、できれば Web 上でテキストエリアにコードを貼り付けて「実行」ボタンを押せばすぐにテストできると幸せです。

インタプリタ言語であれば、例えば PHP では PHP Interactive というツールでそれが行えるのですが、C++ でも同様のことができる環境がありました。以前、サイボウズ・ラボの akky がブログで紹介していたのですが、codepad.org というサイトでそれが行えます。また C/C++ だけでなく、各種言語について、ブラウザ上で編集・実行が行えるようになっています。私もときどき使っていますが、結構便利です。

2008年05月12日

まずはテーブル定義

畑です。

サイボウズ Office X のプロトタイプ開発のフェーズは大きく2つに分けられます。1つ目はWebアプリケーション(CGI)としてのフレームワーク部分で、もう1つがグループウエアとしてのアプリケーション部分です。フレームワーク部分の設計方針については何となく固まりました。そこで、いよいよアプリケーション部分の設計方針を固めようと調査に入っております。

アプリケーション部分のプロトタイプ開発においては、今回からデータベースに MySQL を採用するので、実装に入る前に何はともあれテーブル定義を固める必要があります。テーブル定義においては、後からこの機能が必要だからといって変更すると、別の機能の部分の SQL がうまく記述できなかったりすることがあります。したがって、最初の時点でアプリケーションに必要とされる機能を見極め、その機能が表現できる SQL を確認することにより、テーブル定義を固めていく必要があります。

サイボウズ Office シリーズの場合、もうかれこれバージョン7まで来ているので、アプリケーション数も多いです。また、アプリケーションに共通で必要となるユーザーやグループの概念と、各アプリケーション固有の部分とが存在し、さらに添付ファイルなんかも複雑に絡むので、テーブル定義を固めるのは容易ではありません。

ここで固めたテーブル定義がおそらく何年か使用され続けることになるので、かなり慎重に行う必要があり、結構、悩んでおります。

そういえば、サイボウズはサイボウズ ガルーンという MySQL の実績があるグループウェアがあったではないか。是非、参考にせねば!

と思って、ガルーンのテーブル定義を拝見してみたのですが、

なんと約750テーブル。。。。
「クエリーもきてますよ」とガルーン開発関係者に言われました。

参考にするのにも時間がかかりそー。

ガルーンの2.0の初期版には僕も開発に関わっていたのですが、ガルーンもバージョンアップを重ねるにつれチューンナップされ性能もアップしています。テーブル定義にもその工夫が現れているのでしょう。

2008年05月21日

社外グループウエア AltSpace の紹介

畑です。

イントラネット(社内)のグループウエアと言えば、サイボウズ Officeサイボウズ ガルーンがあげられますが、今日は社外(自分の組織外)の人とコミュニケーションを行うためのグループウエア AltSpace を紹介したいと思います。

AltSpace とはサイボウズ・ラボで開発され、サイボウズ本社と共同で運営されているサービスです。社外・組織外の、例えば、同窓会、同期会、前職の仲間などの限られた人々と、掲示板を通じてコミュニケーションを行うことができます。

AltSpace を利用するには、既に AltSpace の会員となっている人から招待を受けるか、または「サイボウズ(R) ネットID」のアカウントを新規に作成することにより AltSpace を利用できるようになります。

無料で利用して頂けるようになっております。

AltSpace はデータベースに MySQL を利用して開発されているので、同じグループウエアとして次世代のサイボウズ Office X の開発の参考にしています。特にテーブル定義については AltSpace の開発の際に吟味した内容がかなり活かせると踏んでいます。

2008年05月29日

本の紹介:デザイニング・インターフェース

畑です。

今日は現在読んでいる本を紹介したいと思います。「デザイニング・インターフェース~パターンによる実践的インタラクションデザイン」という本です。アプリケーションソフトウェアで良く使われるユーザーインターフェースをパターンに分類して、パターンごとにどのような場面で使うべきかなどが簡潔に説明されていて、よくまとまっています。例の画面のスクリーンショットも非常にカラフルで分かりやすくなっています。去年(2007年)の1月に第1刷が出版されているようなので、もっと早く読んでおけば良かったと思いました。

次世代サイボウズ Officeの開発でも参考にしたいと思います。

2008年06月03日

明日のグループ社内発表会でサイボウズ Office X の進捗を報告

畑です。

明日はサイボウズ・ラボで4ヶ月に1度行っている研究開発発表会です。発表者はラボのメンバーで、参加者はグループ会社の人達になります。

そして、明日の発表会でサイボウズ Office X プロトタイプ開発の進捗を報告する予定です。まだまだ社外には公開できない内容なのですが、発表内容の目次だけでも公開したいと思います。

1. 概要
2. 要件
3. CyDE1.5
 ・ 開発言語
 ・ Webアプリケーション・フレームワーク
 ・ テンプレートエンジン
4. Office X
 ・ 旧バージョンからのデータコンバート
 ・ 新機能の提案 to PM

「3. CyDE1.5」ですが、社内的にサイボウズ Office 7 までの開発フレームワークを「CyDE1.0」と呼び、ガルーン2.xの開発フレームワークを「CyDE2.0」と呼んでいるので、何となくその間をとって「CyDE1.5」と呼んでいます。

「開発言語」の項では、「C++で開発」で述べたような内容を発表します。

本ブログでも以前「テンプレートエンジン」について述べましたが、CyDE1.5におけるテンプレートエンジンについても説明します。

また「ハイブリッド・コンバーター」の回でデータコンバーターについて触れましたが、「旧バージョンからのデータコンバート」の話もあります。

それから製品として世にリリースされるときには機能として提供されるかどうか分かりませんが、プロトタイプ開発の側からの「新機能の提案」も行おうと思っています。

2008年06月10日

typedef には少し注意

畑です。

今日は C++ の話を1つ。

MySQL のラッパークラスを作ろうと

Database.h
struct MYSQL;

class Database
{
protected:
    MYSQL *m_pMySQL;
    ...
};
Database.cpp
#include "Database.h"
#include <mysql.h>

Database::Database()
: m_pMySQL(NULL)
{
}
としたのですが、「'MYSQL':再定義されています。」というコンパイルエラーが出ました。

struct MYSQL; とやって、ポインタとなるメンバー変数を定義できるようにしておき、後で #include <mysql.h> 内で struct MYSQL を定義しようというのが意図です。「struct ではこの方法が使えないのかなあ。確か class では使えたはずなのに」と思いましたが違いました。<mysql.h> 内を良く見ると、
typedef st_mysql
{
    ...
} MYSQL;
となっていました。ですから、struct MYSQL; ではなく、struct st_mysql; とすればコンパイルは通りました。

2008年06月24日

バックグランドでコンバート

畑です。

以前、ハイブリッド・コンバーターと題して、現バージョンから次期版へのコンバートの方式に関するアイデアを説明しましたが、ちょうど今月実際のデータを使ったコンバート実験を行っているところです。

オンデマンドで、またはバックグランドでコンバートを行う旨の解説を以前の記事では行いましたが、最近はバックグランドで行う方向に傾きつつあります。そこで、バックグランドでの方式をもう少し詳しく説明したいと思います。

ユーザーの環境によっては、多数のユーザーで長い間サイボウズ Office シリーズを使用している環境もあれば、少数のユーザーで比較的短い期間しか利用していない環境もあるでしょう。蓄積されたデータのサイズが小さいユーザーであれば、バックグランドで行うといっても、すぐに完了してしまうかもしれませんが、サイズが大きいユーザーであれば動作しているマシンのスペックにもよりますが、何時間か、場合によっては1日以上時間がかかるケースがあるかもしれません。しかし、コンバートに時間がかかりすぎると業務に支障をきたすことになります。

そこで、バックグランド方式ではコンバートが完全に完了していないくても使用を開始できることを前提に考えています。コンバートするデータの順番に優先順位を付けておいて、使用開始に最低限必要なデータのコンバートが完了した後に、その他のデータを順次コンバートしていく方式です。そのかわり、コンバート中にアクセスしていてもトラブルが起こらないように設計する必要があります。

使用開始に最低限必要なデータとは、例えば以下のようなデータです。

・ システム設定データ
・ 個人設定データ
・ 未来のスケジュールデータ
・ 未完了のToDoデータ
・ 進行中のワークフローデータ

そして、その他のデータについては、参照頻度の高いデータが優先順位として高くなります。アプリケーション別にみていきますと、例えば以下のようになります。

・ 掲示板データは最終更新日時が近い順番に
・ 過去のスケジュールデータは昨日のスケジュールから順番に過去に

あと、バックグランド方式の場合、コンバート中にアクセスされることを想定するので、どの程度コンバートが完了しているかをアクセスしているときに表示する仕組みが必要であると考えています。

2008年07月10日

Google Protocol Buffer

畑です。

先日 Google から Google Protocol Buffer というデータ交換ツールがオープンソース化されました。

グーグル、XMLに代わるデータ交換ツール「Protocol Buffers」をオープンソース化

XMLに変わるものということですが、テキストである必然性がない場合であれば、つまりバイナリ形式でも問題ないのであれば、データサイズを小さくできるし、読み書き速度も上がるので良いと思います。

Java, Python, C++ に対応とのことですが、サイボウズ Office X も C++ で開発しているので、使えそうな場面がありそうです。

プロジェクトページの Quck Example を見るかぎりでは、ファイルストリームへの読み書きもサポートしているようなので、データベースに保存しないデータをファイルに保存する場合にも使えそうです。また、データベースへの保存においても、設定情報などを固めてBLOBのカラムに保存するような使い方ができそうです。

About Office X

ブログ「サイボウズ Office 開発ブログ」のカテゴリ「Office X」に投稿されたすべてのエントリーのアーカイブのページです。過去のものから新しいものへ順番に並んでいます。

前のカテゴリはOffice 8です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。