Back Home Next

E5:マクロの参照

CommandBarV1.2の説明書には、あまり詳しく書かなかったのですが、コマンドボタンに登録するマクロ名にワークブックの名前の指定が必要でした。たとえばマクロがTESTでそのマクロがTESTWorkBook.XlsのExcelファイルに入っているとして、CommandBarを使ったワークシートには以下のように書く必要がありました。

 TESTWorkBook.Xls!Test

新しいV1.3ではコマンドボタンにマクロを登録するときにマクロ名にワークブック名が無ければこれを追加して登録するようにして、書く必要が無いように修正しました。

マクロにワークブック名の指定が必要なのは、おかしな現象です。アクティブなブックのマクロがワークブックを指定しないと呼び出せないのはどうも合点がいきません。普通はマクロが登録されるブックとそのマクロをメニューに登録するプログラムがあるブックは同一なのでこの問題は出てくる事は殆んどないでしょう。
しかし、CommandBarではアドインから別のブックのマクロを登録するので、ワークブックを指定してマクロを登録しないと問題が出るようです。

それもアドインの中のマクロと重複したマクロを登録するとマクロにブックを指定しなくても正しく動作するので、単純にアドインがブックとして指定されるようではないようです。

原因は不明ですが必ず、マクロ名にブック名をつけて扱うようにすれば、問題はでないとおもいます。


E6:ワードのテーブルを読み出す

ワードもオフィスファミリーですのでVBAが使えますが、あまりワードのVBAを使うチャンスはないと思います。私はワードについてあまりよい印象はもっていません。英文のワープロから作られただけあってどうしても日本語との相性が悪いし安定性もよいとはいえません。Excelがあってのワードなので仕方なく使わざるを得ないのがほとんど人の実感ではないでしょうか?あと外国と文書やりとりからどうしてもワードになってしまいます。しかしオフィスファミリですのでVBAが同じく使えるのは大きなメリットです。

長くワードVBAを使う機会が無かったのですが、ワードの差し込み印刷のデータをデータベースで処理する必要があり、プログラムを作る必要にせまられてワードVBAを使いましたので、ここに簡単に説明します。ワードVBAの解説本も殆どが絶版になっていて仕方がないのでワードVBAのヘルプの助けで作成しました。そのヘルプもA,B,C順のレファレンスのみでオブジェクトの体系的な説明はありません。

ワードオブジェクトの構成は

Applivcation-Documents-Document

Applicationはワードのクラス(Word.Apllication)で作成されるワードそのものです。Applicationには多数のオブジェクトが含まれますが、Documentオブジェクトが一番代表的なオブジェクトで、ワードで開かれた文書そのものです。

そのDocumentオブジェクトにも多数のオブジェクトが含まれて代表的ないくつかを紹介すると

表は Document-Tables-Table-Cells-Cell
段落は Document-Paragraphs-Paragraph
フィールドは Document-Fields-Field
文書データそのものは Document-Range や Paragraph-Range

TableやParagraphやFieldには名前プロパティがなく、インデックス番号で指定します。ですので文書の中の順番を意識して指定する必要があります。
では具体的な使い方を説明します。まずデータが含まれるワードオブジェクトの生成の仕方です。

Dim MyWord as Object
Set MyWord = CreateObject("Word.Application")
MyWord.Documents.Open "C:\Myocument\差し込み印刷.Doc"

Microsoft Word 8.0 Object Libraryに参照設定してあれば

Dim MyWord as Word.application
Set MyWord = New Word.Application
MyWord.Documents.Open "C:\Myocument\差し込み印刷.Doc"

とも書けます。閉じるときもExcelと同じく MyWord.Quit と書きます。

テーブルのオブジェクトは
Tables-Table-Rows-Row-Cells-Cell または Tables-Table-Columns-Column-Cells-Cell の構成を取ります。

ではテーブルがワード文書ファイルに一個、もしくは最初にある場合として、アクセスするにはインデックス番号が1なので

Dim i,,j as Long, V as Variant
With MyWord.Documents("差し込み印刷.Doc")
 For i = 1 to .Tables(1).Rows.Count -1
  For j = 0 to .Tables.Columns.Count - 1
    V = Rows(i).Cells(j)
    Msgbox "表の行" & i & ”列” & j & ’のデータは” & V
  Next j
 Next i
End With

以上わかるようにオブジェクト、クラス名が異なるだけで同じ表現でプログラムができます。これもオブジェクト指向プログラミングの恩恵になります。
WordVBAはかなりスピードは遅いですので多量のデータを処理するのには向きません。表の2-3行を取り込みのに1秒以上かかりますのでそのつもりで利用してください。

E7:グラフオブジェクトのデータソースにアクセスする

拙作ChartTbSumではグラフのデータテーブルに合計欄を追加する機能があります。このようなことを実現できるのもオブジェクトプログラミングの成果です。グラフはグラフクラスから作られたオブジェクト(インスタンス)でグラフ作成のプログラムと共にグラフを作成したデータも一体になっています。ですのでグラフからデータを呼び出し、合計を計算し合計欄を作成できるのです。
グラフオブジェクトにはデータを示すオブジェクトSeriesCollectionが含まれます。

Chart - SeriesCollection

SeriesCollectionはコンテナでデータの系列の数だけあります。以下はその構造です。

系列の名前のセル、X軸の各項目名のセル、系列のデータセル

最初の系列の名前のセルは1個、残りの2つはX軸の項目数のセル数があります。ChartTbSumでは系列を跨いで計算しますので、このままでは使いにくいので系列を集めたセル集合を作る方法を紹介します。
SeriesCollectionのFormulaプロパティを使ってセルの分解と集合を行います。

SeriesCollectionのFormulaは次のの文字列になります

=SERIES(シート名!セルアドレスK0、シート名!セルアドレスK1、シート名!セルアドレスK3、N)

セルアドレスK1:系列の名前のセルのアドレス 例 $B$1
セルアドレスK2:X軸の各項目名のセルのアドレス 例 $A$2:$A$10
セルアドレスK3:系列のデータセルのアドレス 例 $B$2:$$B$10
N:系列の番号を示します。

MyChartグラフオブジェクトのn番目のSeriesCollectionから各セルを取り出す方法を示します。

Dim RangeK( 1 to 3) as Range、ChartSeriesFormula as String
ChartSeriesFormula = myChart.SeriesCollection(n).Formula

Sub GetEachRange(ChartSeriesFormula, RangeK)
Dim i as Long
If ChartSeriesFormula Like "=SERIES(*" Then
 ChartSeriesFormula = Mid(ChartSeriesFormula, 9)
 For i = 1 to 3
  set RangeK(i) = Range(Left(ChartSeriesFormula, InStr(ChartSeriesFormula, ",") - 1))
  ChartSeriesFormula = Mid(ChartSeriesFormula, InStr(ChartSeriesFormula, ",") + 1)
 Next i
End If
End Sub

後はSeriesCollectionの数だけ繰り返して、Union関数で各セルを集合させれば終了です。

Dim RangeK( 1 to 3) as Range, KoumokuRange, XRange, DataRange as Range
Dim i as Long
For i = 1 to MyChart.ChartSeriesCollection.Count
 Call GetEachRange(MyChart.ChartSeriesCollection(i).Formula, RangeK)
 Set KoumokuRange = Union(KoumokuRange、RangeK(0))
 If i = 1 then
  Set XRange = Range(1)
 End If
 Set DataRange = Union(DataRange、Range(2))
Next i


E8:Shapeを使ってデータテーブルを作る

グラフのデータを取得する方法はE7で説明しましたが、ではそのデータから合計欄の表を作るにはどうすればよいのでしょうか。テーブルを作成するために図形オブジェクト(Excelの作図機能)を使います。オブジェクト名はShapeです。


Sheets - Shapes - Shape

各図形はそれに対応するメソッドで作成され、Shapesコレクションに登録されます。HelpでShapesを引けばメソッドを参照することができます。

テキストボックス AddTextbox
規定の図形は   AddShape
直線は      AddLine
曲線は      AddCurve

今回はAddTextboxメソッドでテキストボックスを作成してそれをつなぎ合わせてデータテーブルにします。ではまず一個のテキストボックスを作成するには

With ActiveSheet
With .Shapes.AddTextbox(msoTextOrientationHorizontal, Bleft, Btop, BWidth, BHeight)
.Line.Visible = msoTrue
.Name = "TX" & n
End With
End With

msoTextOrientationHorizontal は横書きを、Bleft, Btopは文字どうりテキストボックスを配置するシートの上の位置を、Width, BHeightはテキストボックスのサイズを示します。.Line.Visible = msoTrue で枠が見えるようにします。.name = "TX" & n で後で名前でコレクションの中から探せるようにNという番号を付けて名前を付けておきます。

先ほど作成したテキストボックスに文字とそのフォントサイズ等をセットするには

with Activesheet.shapes("TX" & n).TextFrame
.Characters.Text = "Text Value"
.Characters.Font.Size = Fsize
.Characters.Font.Bold = False
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With

以上で1個のテキストボックスを作成できますので、縦横必要な個数のテキストボックスを隣り合わせで繋いで、拙作ChartTbSumでは合計欄を作成しています。

Back Home Next


Copy Right 2001- Ken