Feeds:
投稿
コメント

Archive for the ‘devs’ Category

ColorIndexをEnumにする

未だにWin8にアップグレードできていません

さて、今回はExcelその他のColorIndexを列挙子にしてみます。(作ってからググったらあったけど気にしない)

ColorIndexはColorと違い定義済みの色をそれに対応する整数値から取得、設定することができます
ですがこの整数値はIntegerで入れる形となっていて非常に扱いづらいです(というのもどれがどの色に対応しているかが数字から見えないため)

というわけで数字と対応する列挙子を作成します。列挙子はIntegerで宣言しておけばIntとしても使えるためです

ColorIndexをカラーコードに変換した表についてはググったりすれば簡単に出てくるので楽だと思います。
ちなみに私はhttp://d.hatena.ne.jp/ogohnohito/20110512/p2を参考にさせていただきました
またカラーコードと色名についてはhttp://e-words.jp/p/r-colornames.htmlのほうを参照しました

とりあえず次のような感じ

Public Enum ColorIndexEx
        ''' <summary>
        ''' #000000,ColorIndex = 1に対応する
        ''' </summary>
        Black = 1
        ''' <summary>
        ''' #FFFFFF,ColorIndex = 2に対応する
        ''' </summary>
        White = 2
        ''' <summary>
        ''' #FF0000,ColorIndex = 3に対応する
        ''' </summary>
        Red = 3
        ''' <summary>
        ''' #00FF00,ColorIndex = 4に対応する
        ''' </summary>
        Lime = 4
        ''' <summary>
        ''' #0000FF,ColorIndex = 5,32に対応する
        ''' </summary>
        Blue = 5

End Enum

1から56まであります
少し重複があるのでそこをはじく必要があるので注意

ついでにxlColorIndexについても定義していまうと置き換えられるかと

さて、一つだけ問題があります
17以降がHTMLのカラーコードとしてないという事態です
#9999FFは何色なんでしょうか…

苦肉の策で_9999FF = 17とか宣言してますがなかなかひどい

一応ソースはhttps://bitbucket.org/fantasticswallow/intellioffice/src/ab714c2581f617d3f443c903fca39b3998ab1d64/IntelliOffice/ColorIndexEx.vb?at=defaultに転がっていますので適当に使いたければ(一応Ms-PLにしたいんですけどどうしたらいいんですかね)

とりあえずこの辺で

Read Full Post »

VB.NET 11の新機能を最近知ったなど

さて、Yieldってなんだって話からですがこれはC#には2.0の時くらいからすでにあるyield returnの機能です
Yieldでyield returnが実行されます。yield breakはなさそう

ちょっと少し話が前後しますが最初に戻して進めます

・VB.NET 11での新機能
http://msdn.microsoft.com/en-US/library/we86c8x2.aspxを参照にしながら

書いてあるのは次の通りですね
・Async/Await
・Iterator/Yield
・呼び出し階層
・メソッド情報
・Global Namespaceのサポート

簡単なのはGlobal Namespaceですかね。これは今までルート名前空間に強制的に所属させられていたVB.NETですがGlobalを最初につけることでルート名前空間をつけなくて済みます
つまりSystem.linqに新しくクラス追加しようと思ったときいちいちルート名前空間をSystemにしなくてもGlobal.System.linqにすればいいわけです

メソッド情報は引数に属性をつけることで引数として現在の実行メソッド情報をとれる…?やつなんですかねぇ。これは分かりません

呼び出し階層はスタックトレースみたいのが取れるんじゃないかなぁと

Async/Awaitは非同期待機のやつですね。いくらでも書いてありそうなのでここではスルー

さて、最後にIterator/Yieldですがこれは反復子を指しますIteratorで宣言された関数はReturnの代わりにYieldで返す必要があります

・Iterator/Yield
ちゃんと見ていきます

[accessmodifier] Iterator (Function|Property)の戻り値はIEnumerable(Of T)またはIEnumerator(Of T)となります。(?) 
またYieldは遅延実行することを示します。

Yieldは主にLINQで使われてたりするものです。つまるところ必要になるまでメソッドは実行されずに必要になったら評価されて実行されます。
少しコードを書いて試してみましょう

・yield returnの実行順序
次のようなソースコードを用意します。コンソールアプリケーションです

Private Iterator Function GetIterator(xcol As String) As IEnumerable(Of Char)
    For Each xch In xcol
        Yield xch
        Console.WriteLine("validation value")
    Next
End Function

Sub Main()
    Dim testArgs As IEnumerable(Of Char) = GetIterator("abcdefghijklmnopqr")
    For Each x In testArgs
        Console.WriteLine(x)
    Next
    Console.WriteLine("end test")
End Sub

この実行結果は次の通りです

画像のとおり、yieldでリターンするとYield句まできた時点でメソッドはブロックされ、元の処理に戻されます。
そのためYieldの下のブロックは戻ってきたときにふたたび次のYieldまで実行されます

そのため上の画像のようにFor Each中に値の評価を行います。For Eachしたからといってすべてが一斉に返されないのも特徴といえるかもしれません

・Whereを実装してみる
yield return知りたいならLINQのWhereとか実装するといいといわれたので

自分でVB.NETでWhereを実装すると次のような感じです

Private Iterator Function myWhere(Of T)(source As IEnumerable(Of T), predicate As Func(Of T, Boolean)) As IEnumerable(Of T)
    For Each x As T In source
        If predicate(x) Then Yield x
    Next
End Function

これで次のようなコードを実行してみます

Sub Main()
    Dim testArgs As IEnumerable(Of Integer) = Enumerable.Range(1, 200)
    For Each i In myWhere(testArgs, Function(x) x Mod 5 = 0)
        Console.WriteLine(i)
    Next
    Console.WriteLine("end test")
End Sub

実行結果は…まあ普通のWhereの結果です

Selectは次のような感じでいいのかな?(テストできてない)

Private Iterator Function mySelect(Of T, TValue)(source As IEnumerable(Of T), predicate As Func(Of T, TValue)) As IEnumerable(Of TValue)
    For Each x As T In source
        Yield predicate(x)
    Next
End Function

・どこで使うの
まあ基本はLINQみたいにコレクション操作になるとは思いますがYieldでやる必要がありなおかつLINQでサポートされてないメソッドというのがそんなにたくさん出てくるのか微妙な気は
そもそも.NET Framework 4.5なのでLINQでサポートしてる内容をわざわざYieldで使う必要ってないんですよね

LINQの理解のために使うとかLINQわからないからYield… くらい…?
それよりはやっぱりLINQとかでサポートしてないやつになるかなぁ…


結局使用方法が見いだせず…
というか前半の文面なんも考えてなかったせいでわかりづらいですね

とりあえずこの辺で

Read Full Post »

作ろうと思ってたライブラリの内容がもろ入ってて笑うどころではないなど

というわけでVSTO Power Toolsのお話です。4年は前のツールですね
これのインストールのためだけにVisual Studio 2008入れることになるとは…

Microsoft Visual Studio Tools for the Office System Power Tools v1.0.0.0はVSTO向けの便利なアプリケーションや拡張アセンブリを提供してくれるものです
OpenXMLのビューアやビルトインされたリボンのコントロールIDを選択したり?するアプリケーションなどを含んでいます。アプリケーションの方は興味があったら調べるといいかもしれません

今回話題にするのはOffice Interop API Extensionsという拡張アセンブリの方です。これの説明には”A set of C# classes for handling parameterized properties and optional/named parameters, as well as for LINQ-enabling Office collection objects.” とあります。つまりOptionalなプロパティのObjectにされてた部分をしっかり型の関連付けを行い、LINQを使えるようにもしたよって感じです

まず一つ目になんで型の関連付けがすごくいいかというお話ですがVSTOではこんな感じのメソッドが多めに用意されています

Microsoft.Office.Interop.Excel.PivotTable PivotTableWizard(
    [object SourceType = System.Type.Missing], 
    [object SourceData = System.Type.Missing], 
    [object TableDestination = System.Type.Missing], 
    [object TableName = System.Type.Missing], 
    [object RowGrand = System.Type.Missing], 
    [object ColumnGrand = System.Type.Missing], 
    [object SaveData = System.Type.Missing], 
    [object HasAutoFormat = System.Type.Missing], 
    [object AutoPage = System.Type.Missing], 
    [object Reserved = System.Type.Missing], 
    [object BackgroundQuery = System.Type.Missing], 
    [object OptimizeCache = System.Type.Missing], 
    [object PageFieldOrder = System.Type.Missing], 
    [object PageFieldWrapCount = System.Type.Missing], 
    [object ReadData = System.Type.Missing], 
    [object Connection = System.Type.Missing])

こんなメソッドどうでしょうか

何がすごいってまずVSTOなのにインテリセンスが使えないところにあります。それなりにはでますけど…
というか何入れていいのかこれだけじゃさっぱりわかりません。下手なの入れると動かないですし

これを拡張メソッドで簡単に書き換えるとこんな感じになります(VBですが)

'' <summary>
        ''' Worksheet.PivotTableWizardを実行します
        ''' </summary>
        ''' <param name="target"></param>
        ''' <param name="SourceType">レポートの集計元データの内容を示す定数。この引数を指定する場合は引数SourceDataも指定。
        ''' SourceTypeとSourceDataを省略した場合、集計元データの種類はxlDatabaseとされ、集計元データは名前付きセル範囲Databaseから取得されます。
        ''' 名前付きセル範囲Databaseが存在しないときに、現在の選択範囲がデータを含む10以上のセルの場合は、その選択範囲が使われます。そうでない場合はエラーが発生します。</param>
        ''' <param name="SourceData">レポートの作成に使うデータ。Rangeオブジェクト、セル範囲の配列、他のレポートの名前を表す文字列定数のいずれかを指定可能。外部データベースの場合、引数SourceDataは、各要素が255文字の長さまでのSQLのクエリ文字配列を格納。
        ''' 引数Connectionを使って、ODBC接続文字列を指定。以前のExcelのバージョンとの互換性について、SourceDataでは2つの要素配列を指定できます。
        ''' 1番目の要素はデータのODBCソースを指定した接続文字列です。2番目の要素はデータの取得に使用するSQLのクエリ文字列です。引数SourceDataを指定した場合、引数SourceTypeも指定する必要があります。
        ''' 引数SourceDataの範囲内にアクティブセルがある場合は、引数TableDestinationも指定する必要があります。</param>
        ''' <param name="TableDestination">レポートの配置場所を表すRangeオブジェクト</param>
        ''' <param name="TableName">新しいレポートの名前</param>
        ''' <param name="RowGrand">レポートに行の総計を表示するかどうか</param>
        ''' <param name="ColumnGrand">レポートに列の総計を表示するかどうか</param>
        ''' <param name="SaveData">レポートと共にデータを保存するかどうか。Falseの場合はレポートの定義のみ</param>
        ''' <param name="HasAutoFormat">レポートの更新時やフィールドが移動されたときに、オートフォーマットを実行するかどうか</param>
        ''' <param name="AutoPage">SourceTypeにxlConsolidationを指定した場合にのみ有効。統合元範囲のページ フィールドを自動的に作成するかどうか。
        ''' False に指定した場合は、ページ フィールドは自分で作成する必要があります。ページ フィールドは複数作成することができます。</param>
        ''' <param name="BackgroundQuery">レポートのクエリをバックグラウンド(非同期)で実行するかどうか</param>
        ''' <param name="OptimizeCache">ピボットテーブルのキャッシュの構成時に最適化を行うかどうか</param>
        ''' <param name="PageFieldOrder">ピボットテーブルレポートのレイアウトに追加するページフィールドの順序</param>
        ''' <param name="PageFieldWrapCount">ピボットテーブルの各列または各行のページ フィールドの数を指定</param>
        ''' <param name="ReadData">外部のデータベースのすべてのレコードを含む、非常に大きなピボットテーブルキャッシュを作成するかどうか。Falseの場合、実際のデータを読み込む前に、いくつかのフィールドをサーバーを基にしたページフィールドに設定できます。</param>
        ''' <param name="Connection">ODBCデータ ソースと接続できるようにするODBC設定のいずれかを含む文字列。接続文字列は"ODBC;[接続文字列]"形式です。
        ''' この引数は、PivotCache オブジェクトの Connection プロパティの設定よりも優先されます。</param>
        ''' <returns></returns>
        ''' <remarks>Reservedは使用不可につき常にnullがわたります</remarks>
        <Extension()>
        Public Function PivotTableWizard(target As Worksheet,
                 Optional SourceType As XlPivotTableSourceType = Nothing,
                 Optional SourceData As Object = Nothing,
                 Optional TableDestination As Range = Nothing,
                 Optional TableName As String = Nothing,
                 Optional RowGrand As Boolean = Nothing,
                 Optional ColumnGrand As Boolean = Nothing,
                 Optional SaveData As Boolean = Nothing,
                 Optional HasAutoFormat As Boolean = Nothing,
                 Optional AutoPage As Boolean = Nothing,
                 Optional BackgroundQuery As Boolean = False,
                 Optional OptimizeCache As Boolean = False,
                 Optional PageFieldOrder As XlOrder = XlOrder.xlDownThenOver,
                 Optional PageFieldWrapCount As Integer = 0,
                 Optional ReadData As Boolean = Nothing,
                 Optional Connection As String = Nothing) As Microsoft.Office.Interop.Excel.PivotTable

これでもまだ残念な気はしますけどマシではありますね(実際使うかといわれると微妙ですが)(そもそも引数が多い)

こういうのを全部~~Argsという形でまとめてあるのが拡張アセンブリの方です。これによって基本的に引数1つだけできれいに実行できるようになりました。 やってることはMissingへの変換があるせいで微妙に汚いですけど…

次にLINQのサポートのほうなんですけどこれはいくつかのメソッドにIEnumerableを返すItemsという関数が定義されています。中身はオブジェクト本体をyield returnしています。(ILゲフンゲフン)
yield returnなんてVBにないから気づかなかったのか…!(違う) とか思いながらこれを実装すれば何かに使えるかも知れませんね
(まあCOMObjectの壁を越えれるのかは知りませんが…)(どっちかっていうとCastに近い感じが)

さてそんな感じでこんなアセンブリもあるよって話ですが実はこのツール、VS2008までしか対応していません。Officeも12までです。便利なのに今は使うことができないという悲しい現実

VS2008を今でも使ってる方はぜひどうぞ! って感じですがいまさらVS2010も2012でもないのを使うのはちょっと

自分でとりあえず作ってみるかなー的な感じのことは思ってたりですけどね

あとこれ調べてて感じた結論は
「VSTOはC#も使えるんじゃなくてC#のためのOffice開発」
って感じですね。VB.NETなんてなかったんや…

とりあえずこの辺で

Read Full Post »

タイトル考えるのだけは楽しいですね

Office 2013は現在もっともWindows 8のデスクトップアプリケーションのあるべき姿をとっているということができると思います。そもそも現在Windows 8向けのデスクトップアプリケーションというものはないのではないかと思います。というのもたいていはWindows 7以前向けのアプリケーションを使っているためです。
しかしOffice 2013は完全にWindows 8を意識して作られています。これはWindows 8、ならびにこれからのWindows デスクトップアプリケーションのあるべき姿である、そんな風に思います。というわけでOffice 2013のUIなどを見ながらどうしていけばよいかなんかを考察していきます

・増える入力形式
今までのWindowsでは基本的にマウスとキーボードの入力が主流でした。Windows 7からマルチタッチをサポートしましたが実際には対応したデバイスが多く出なかった点や単純にWindows 7をそのままタッチデバイスに持って行ったためあまり操作性が高いといえるものではありませんでした(標準のコントロールのpxとかうんぬん)

しかしWindows 8からはタッチとペンも主流の入力形式としてサポートしていく形になります。これが示すことはつまりどんな入力デバイスからでも操作できる可能性 というものが必要になってくるわけです。たとえば11pxのListBoxのアイテムを直列に並べたらどうなるでしょうか? 間違えずにちゃんと押せるのか といわれると間違えるかもしれない という回答になることでしょう。最低でも何たらpx以上とかなんとかってどこかにあった気がしますが本当にWindows 8などに対応したデスクトップアプリケーションを作るうえではとても大事になっていくことと思います

・UI表示方法を変えるタッチモード
タッチモードはすべてのOffice製品に追加されているUIレイアウトを変更するモードです。次の二つの画像を見てみましょう

現在のOutlook 2013の画像です。上が標準モード、下がタッチモードです。タッチモードのほうはオレンジで囲ってある部分が変更部分です。リボンUIのボタンレイアウトが通常より大きめにとられているのが分かると思います。またリストアイテムも大きめになりよく使うコマンドは右側にコマンドバーとしてまとめられているのが分かると思います。さて、この時どのようなことが行われているのかをもうちょっと検証してみましょう。次に4枚の画像を示します

はい、ということでリボンUIコントロールとリストアイテムを拡大して横にルーラーを配置したものです。どちらも先が標準で後がタッチモードです
リボンUIのほうはわかりやすいように適当に選択してみたのですがこれに誤差があるとすればボタンの大きさは同じといえることが分かります。リストアイテムの方は17px→26pxとなり事実上大きくなってはいますがフォントサイズはどちらも11pxとまったく同じです
つまりタッチモードで調整してるのはマージン部分である という風に言えると思います。マージンとグリッドが大きくなっていますが中のコントロール自体はそのままになっているためタッチへの対応はマージン調整を行えるようにするだけでもだいぶできるのではないかという風に感じます

・シンプルなアイコン
Office 2013になってからリボンUIのアイコンはだいぶシンプルになりました。これはModern UI(だっけ?)に影響を受けたものといえるかもしれません。 2010と2013のリボンを並べてみるとこんな感じです

アイコンの形なんかも結構シンプルになりましたね。まあこの辺は手間が大きい可能性もあるしなんともいえないですけど

・IMEから見るキーボードとタッチの違い
情報そのまま垂れ流しです。タッチキーボードと通常のキーボードではIMEの予測変換の出方が違います。タッチでは縦に並べると誤操作が多くなるため横にならべていてキーボードだと縦となっています

UIのコンテキスト依存
これなんかもはや調べてない…
Office 2013では特定のメニューにおいてタッチで開くかマウスで開くかに応じてメニューのレイアウトが切り替わるというものがあります。おもにはコンテキストメニューやカラーピッカーなどとなります。参考としてはhttp://blogs.technet.com/b/microsoft_office_/archive/2012/08/14/office-office.aspxなんかがいいと思います。私のこの記事の全部の内容が書いてあります(

・実際どうしたらいいのか
どうせ対応するなら今からやっとくといい気もしますがその辺は滑らないことを願いつつ
デスクトップアプリケーションは現状マウスとキーボードのみをターゲットとしてるものが多いので新規に作るときにこういう点を考えてもいいかもしれません。既存のアプリケーションに加えるならやはりOfficeみたいにタッチモードの導入が一番いいかもしれません。またはリボンUIみたいにコントロールが大量に列挙されるようなものでないなら最初からタッチモード的な形で作成する という手もあると思います。情報量少し減るのでその辺はよく考える必要はあるかもですが
Officeでタッチモードと標準が共存してるのはリボンUIがスペースとりすぎるという問題があるためなのでそういう問題がないならタッチモード一本で組んでしまうのは十分ありではないかと思います

UIのコンテキスト依存要素についてはControlクラスにMouseDownイベントTouchDownイベントの二つがあるのでこれを使い分けていくという方法がありかなと思います

重要な選択肢は横に並べる方が正確性が出る っていうのも割と大事かもしれませんね

おまけ:リングメニューという新しいメニュー
おまけですがWindowsストア向けのOneNoteにはリングメニューという特殊なメニューが実装されています。これはフリックに近い操作でコンテキストメニューの操作を行えるやたらとすごい代物です。タッチの時代に合わせて新しくコンテキストメニューに代わるものが出るのかもしれませんね


とりあえず今回はここまでで
こんなタイトル負けした記事でよいのか…

とりあえずここまでで

Read Full Post »

Apps for Officeは果たして私の心を揺り動かすものなのか!?

というわけでMSC2012の2日目に取り上げられた新しい開発モデル、Apps for Officeについての記事です
VSTOより優れてるなら使ってみたいですよね

※この記事は2012年9月29日現在の情報を少しまとめたものです。筆者による推測なども当然含んでいます。この記事の内容が正しいということはありませんし突然変わる可能性もありますがそれらについて筆者は一切の責任を負いません

さて、Office 2010までのOffice開発手法には何があったかという話ですがこんな感じ
・VBA(Visual Basic for Applications)
・BCS(Business Connectivity Services)
・Add-ins(Excel,COM)
・Fluent UI(UIカスタマイズ)
・Office Services(SharePointとか)
・Open XML(ファイル操作)

VSTOではAddinとFluent UIができますね。BCSとOffice ServicesはよくわかりませんけどSharePointとか企業向けっぽいのはわかりました。Fluent UIは名前知らなかったけど内容はまあ一応扱ったことある内容

じゃあここに加わるApps for Officeは何を担当するのかという話ですが、それにはまずOffice 2013で何が変わるのかという話から始まります
Office 2013ではこれまで以上にプラットフォームの壁がなくなります。つまりはWindowsだけという時代は終わるわけです
これを実現するためにOffice Web Appsというものがあります。Web上のプラットフォームですね
またスマートフォンなどのデバイスなどにもOfficeは対応するようになっていきます
そんなこんなで新しいデバイスに対応するOffice 2013ですが、これら複数のデバイスでも拡張機能が利用できるようにするためには既存の方法では不可能です(.NET4を動かすとかそもそも無理だったりVBAはセキュリティ面でまずかったり)
ということでセキュリティ面を担保でき複数のデバイスで実行できる拡張機能というものが新しいOffice開発モデルであるApps for Officeです
ちなみに開発手法とかについてはこんな画像があったり

・Apps for Officeの開発方法とは
ということで上でいったようなのがApps for Office(私から見たイメージ)となります
これの開発にはすべてのプラットフォームで使えるという点からHTML5、JavaScript、jQueryが使えます(CSS3が使えるって聞いた覚えがあるんですけどMSDNに書いてない…)
これにより使い慣れた開発ツールを用いてOffice向けのアドインを作ることができます。作ったアドインはOffice Storeに公開することができて、それをユーザーはストアからインストールできるようになります。またこれをSharePoint上?(Exchange?)にInternalなストアを作成してそれをインストール などもできるようになります。
このアドインはドキュメントには一切干渉できません(詳細不明)。またWeb appsにもデプロイできます

・実際どこまで使えるのか
MSC2012のKeynoteなんかではApps for OfficeのデモとしてOutlookに搭載されたApps for Officeの拡張を見たことと思います。そこを見たらやべえ時代来る!とか思ったりします
じゃあどんなことができるの? って話ですよね。現状コンテンツとタスクペイン、メールの3つが主となります
ちなみに現状Apps for Office使えるのがWord,Excel,Outlook,Projectの4つです
チャートに応じて地図を出したり~とかはほんと便利かなぁとか思ったりしますけど何ができるのか! を見てみましょう

・JavaScriptがサポートするREST API
http://msdn.microsoft.com/en-us/library/fp142185(v=office.15).aspx
というところにリファレンスがあります。これを見てみるとそこまでできることが多くなさそうに見えてしまいます
実際一応の用意はされているように思うんですけどなんかOutlook重視感がすごい気がします
Projectはこれサポートしてるのかしてないのかわからないんですけど…

・使い道はあるのか
現状だとOutlookカスタマイズには使えそうなんですけど実際本当に使えるかというと微妙な感じです。API増えないことには話にならない感じはありますね
さすがにBetaという状態で判定下すのは早すぎる気もしなくもないところはあります。しかし今まで干渉不能だったWeb AppsやOffice Mobileを拡張できることを考えると非常にメリットは大きそうです

ちなみにApps for Officeはたぶんどの現状の拡張とも相反しないものな気がしますので(そもそもターゲットプラットフォームが違う気がします)今までの技術は引き続き残るのではないかと思います
ただVBAやFluent UI、Open XML、Addin的な面を将来的にすべてカバーできるなら、どんどん置き換えて行ってすべてのプラットフォームで同じ使い勝手を実現 というのはありかもしれません。現在の状況だとWeb Appsなどの拡張に絞ってリッチクライアントはリッチクライアントで拡張したほうがいいかなと

まとまってないけどこんな感じで

Read Full Post »

MVP for VSTOになりたいとか思うこのごろ(ならもっとちゃんとやれ

VSTO(Visual Studio Tools for Office)ではCOMアドインやVSTOアドインを用いた特殊なファイルを作ることができます。ですが実際はVSTOはVBAほど万能ではありません。それをいかに克服するか ということについてちょっと考えてみます

・VSTOとVBAの比較
そもそもVBAの上位互換がVSTOじゃないのとかそう思う方もいるかもしれないですけど(私が思ってただけかもですが)VSTOとVBAは正確にはターゲットが違います
形もリファレンスアセンブリも同じなのに何が違うんだって話ですけどVBAはアドインが作れなくてVSTOはファイルにアクセスがかなり困難です
(推測かなり含んでるのでここ違うとかありましたらぜひ)
VBAはどちらかというとファイルのための拡張という部分があると思います。VBAのコードは基本的に外部から参照ということでは使わず内部でのみ使用されます。簡単に言えば使い捨てという面があるわけです
VSTOはまったく逆でアプリケーションのための拡張という面があります。実際アドインしか作れません(拡張ファイルもファイルロード時にvstoアドインをロードします)
つまりxlsx系のプロパティのGetを行ったりしてファイルを操作するのがVBAでExcelなどのアプリケーション系の拡張を作成してメソッドの実行やプロパティのSetを行えるのがVSTOといえます

・VSTOとVBAの長所短所
もうちょっと深く考えてみます
VSTOがVBAと比較して優れている点としては
・.NETのアセンブリを利用してアプリケーションを作成できる(LINQ,Rx,etc…)
・言語としてVB.NET/C#を利用できる
・Visual Studioの環境を用いて作成することができる
逆に劣ってる点としては
・ファイルからデータを取得しづらい(COMオブジェクトとして扱われます)
・利用する環境に複数のアセンブリを必要とする(最低でも.NET Frameworkが必須)

ではVBAがVSTOより優れている点としては
・現在のExcelファイル内のデータにアクセスできる
・Excelさえ入っていれば実行可能である(セキュリティ面がうんぬんですが)
・Excelのバージョンはほとんど問わない上拡張子、フォーマットもほぼ問わない
逆としては
・言語にVisual Basicしか利用できない
・アドインを作成して全てのファイルに機能を提供するのが難しい?

などなどがあるわけです(主観)
VBAより新しいからなんとかってわけではないということですね

・VSTOからxlsxファイルへのアクセス手段
そろそろ本題
上記の通りVSTOはGetプロパティがほぼ使えない状態です。じゃあどうしたらいいかという話ですがVSTOのメリットに.NETアセンブリの利用可能があるはずです。これを使わない理由がありませんね

ではいくつか手段を考えてみましょう

・OLE DBによる接続
割とオッフィースらしい接続方法かもしれません。OLE DB(Object Linking and Embedding DataBase)によるxlsxファイルへの接続を行いファイルの情報をDataTableとして扱う手段です。OleDbAdapterを用いて接続するのですがこの時Accessのアセンブリが必要になってくるので注意
まともなクエリ構文が書けないとファイルサイズが大きくなったときにまったく使えなくなるので小さいファイルを扱うだけなら有効かもしれません。なんともいえないですけど

・LINQ to XMLを用いて直接読み込む
何かで見た気がする…? Office2007以降のファイル(~~~x,~~~m)はXMLファイルの集合体をZipファイルにして拡張子を変更しているため(xapと同じ)これを一度解凍してXElementなどを使って読み込む手段もあります
ただしこれをやるにはなぜか分かれているファイル構成に対応できなくてはいけません

・OOXMLを用いて読み込む
私的にはこれがよさげ。OOXML(Office Open XML) SDKを用いて読み込む手段です
先ほど書いた通りファイルはxmlで構成されています。このフォーマットはOpenXMLformatsを使用しているためこれにそった形で読み込めるのがこのOOXML SDKです。もともとはOfficeクライアントを作成するためのものですがファイルサイズが大きくてもちゃんと読み込めるためこれでよいんじゃないかと思います

まあそんなこんなでとりあえずOOXMLについて少しずつ調べて行こうかななどなどと

とりあえずこの辺で

Read Full Post »

調べただけ系記事

VSTOでアドインを作ってそのアドインをファイルごとに設定できるようにするにはどうしたらいいかを考えてみます。たとえばExcelアドインで基本自動で背景を表示するけど特定のファイルだけ表示しないようにしたい とかしたいとします。
(企業とかでプレゼンとかほら)

この時設定をAppDataに書き込むのはあまりよくありません。自分で使うだけなら問題はないかと思いきや一つの環境だけなら となります。2つ以上環境がある場合はAppDataに書き込んで共有でもしない限り話になりません。プレゼンしようと開いたらかわいい女の子が表示されるなんてことはあってはならないわけですね
またopenxmlformatを調べて埋め込むっていうのもありっちゃありかもしれませんけどめんどくさすぎる気がします
(propsあるしできなくはないきがしました)

WPFとかのControlだとTagというプロパティがあるしそういうのないかなーと思ったらCustomDocumentPropertiesがほぼすべてで使えるように思われます。Word、Excel、PowerPointでは使えるみたいです。ほかは調べるのがめんどくさかったんです

CustomDocumentPropertiesはその名の通りユーザー定義のドキュメントプロパティを使用するために使われます

そもそもドキュメントプロパティって何かというとコードでいうならAssemblyInfoに書くような内容のあれです
アセンブリにポインタを合わせるとツールチップで作者名とかでるじゃないですか、あれですあれ

で、BuiltinDocumentPropertiesというものもあるのですがそれはさっきの作者名とか入れる方です。基本的な事項はこっちに入れます
ですけど背景画像を自動表示しないなんてプロパティはないのでユーザー定義という形で埋め込んで使用します

とりあえず追加するなら次のような感じ

Dim dp = DirectCast(CacheInfo.GetInstance.cacheApplication.ActiveWorkbook.CustomDocumentProperties, Microsoft.Office.Core.DocumentProperties)
dp.Add("IsNotShowAutoBackground", False, Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeBoolean,True, )

DocumentPropertiesはOffice.Coreにあるので注意が必要です

DocumentProperties.Add(name,linkToConvert,type,value,linkSource)では主にnameが名前、linkToConvertはセルとリンクするかどうか(bool)、typeは値の型(variantですが実際はMicrosoft.Office.Core.MsoDocProperties)、valueはtypeに該当する型の書き込む値、linkSourceはlinkToConvert時にリンクするオブジェクトを指定します

ちなみにDocumentPropertiesのデータはなぜか__comObject地獄がない気がします。たぶんです。たぶん。今度調べます(

この辺で

Read Full Post »

Older Posts »