目次

マクロ作成

 マクロは、操作手順をBASICコードで表現して
 自動で処理する「手続き」とみればよいでしょう。

 マクロの作成は、プログラミングなので
 操作手順を記録して、冗長な処理を削る
 と考えると、理解しやすいです。

 自分の経験では、高校の入学試験での合否判定を
 自動化できないかと相談を持ち込まれたことで
 マクロを知ることになりました。

 spreadsheetとして、VisiCalcを知っていましたが
 合否判定ではLotus1-2-3を使いました。

 マクロ作成は、プログラミングなので、作成して
 終了とはならずに、テストやデバッグが必要に
 なります。

 テストやデバッグで利用するツールは、以下。




 BASICコードを、一気に動かしたり、1行ずつ
 動かすためのツールが、アイコンで表示されて
 います。

 各アイコンに割り当てされた機能は、後で説明
 しますが、マクロを作成したときは、使うこと
 になると覚えておきましょう。

 マクロは、BASICコードで記述します。
 その一例は、以下。

REM  *****  BASIC  *****

Sub hello_world
    ' variables
    Dim objS As Object
    Dim xcar As String
    Dim xcdr As String
    Dim xstr As String
    Dim xtmp As Integer

    ' substitute
    xcar = "Hello"
    xcdr = "World"
    xtmp = 123

    ' concatenate
    xstr = xcar & " , " & xcdr " ! "

    ' select target
    objS = ThisComponent.CurrentController.ActiveSheet
    ' set pointer
    ptr0 = objS.getCellRangeByName("A1")
    ptr1 = objS.getCellRangeByName("B1")

    ' substitute
    ptr0.String = xstr
    ptr1.Value  = xtmp

    ' message to User
    MsgBox "Completed!"

End Sub

 このマクロを実行すると、セルA1に文字列「Hello , World !」が
 代入されます。

 BASICで記述したマクロの内容からわかることをリスト。

 マクロ作成では、何をしたいのかという仕様を
 明らかにして、紙に手順を書出した後にコード
 に変換すると、効率よく事が進んでいきます。

 操作手順を紙に書出したら、その通りに操作します。
 操作を記録させると、spreadsheetがBASICコードに
 変換してくれます。

 記録機能を利用し、spreadsheetにBASICコードを生成
 させるのが、マクロを効率よく短時間で作成するコツ。

 マクロを司るBASICコードの入力までの手順は、以下。
  1. マクロ記録ができるように、オプションで設定
  2. 「マクロの記録(A)」をクリック
  3. spreadsheetを操作して、一連の処理を入力
  4. 「記録の終了」をクリック
  5. 記録した処理を保存
 この手順で作成したマクロに対応するBASICコードは  LibreOfficeBASICになります。  MicrosoftのExcelと同じにしたいときは   Option VBASupport  を入れておきます。  Option VBASupportは、マクロ記録では効力がないので  BASICコードを入力するときだけに限定されます。  例で用意したマクロは、VBAを使うと次のようになります。 REM ***** BASIC ***** Option VBAScript Sub hello_world ' variables Dim xcar As String Dim xcdr As String Dim xstr As String Dim xtmp As Integer ' substitute xcar = "Hello" xcdr = "World" xtmp = 123 ' concatenate xstr = xcar & " , " & xcdr " ! " ' set object to Cell Cells(1,1).Value = xstr Cells(1,2).Value = xtmp ' message to User MsgBox "Completed!" End Sub  VBAのマクロでは、Rangeで単独セルでも矩形領域指定の複数セルでも  処理できます。  CalcのBASICコードでは、getCellRangeByNameを利用。  ただし、ブックとシートの指定が必要です。  セルに入っている文字列を分割して、他のシートに格納する  マクロをExcelとCalcで作成して、相違を確認します。  対象となるspreadsheetのセルの内容は、以下。  セルB2からセルE3の中に入っている文字列を  分割していきます。  Sheet1のセルの内容を「/」で分割して  Sheet2に展開していくマクロを作成。  Excel   マクロ名を「MySplit」とします。 Dim xidx As String Dim yidx As String Dim zidx As String Dim xstr As String Dim ystr As String Dim i As Byte Dim xlen As Byte Dim xcar As String Dim xcdr As String Sub MySplit() ' set pointer sidx = 2 ' clear cells Sheets(sidx).Range("B2:I3").Value = "" ' loop For i=0 to 7 ' set pointer Select Case i Case 1 : xidx = "B3" yidx = "B3" zidx = "C3" Case 2 : xidx = "C2" yidx = "D2" zidx = "E2" Case 3 : xidx = "C3" yidx = "D3" zidx = "E3" Case 4 : xidx = "D2" yidx = "F2" zidx = "G2" Case 5 : xidx = "D3" yidx = "F3" zidx = "G3" Case 6 : xidx = "E2" yidx = "H2" zidx = "I2" Case 7 : xidx = "E3" yidx = "H3" zidx = "I3" Case Else : xidx = "B2" yidx = "B2" zidx = "C2" End Case ' get context xstr = Range(xidx).Value ' split xlen = len( xstr ) ystr = Right(xstr,7) If xlen = 16 Then xcar = Left(xstr,5) Else xcar = Left(xstr,4) End if xcdr = Left(ystr,4) ' store Sheets(sidx).Range(yidx).Value = xcar Sheets(sidx).Range(zidx).Value = xcdr Next i End Sub  Calc   Calcのマクロは、「Main」から始まるので、サブルーチンと   して呼び出すようにしておきます。 Dim objS As Object Dim xstr As String Dim ystr As String Dim i As Byte Dim j As Byte Dim k As Byte Dim ii As Byte Dim sidx As Byte Dim xlen As Byte Dim xcar As String Dim xcdr As String Sub Main MySplit End Sub Sub MySplit() ' set pointer sidx = 1 ' select object objS = ThisComponent.CurrentController.ActiveSheet ' clear cells For i=0 to 7 objS.Sheets(sidx).getCellByPosition(i+1,1).String = "" objS.Sheets(sidx).getCellByPosition(i+1,2).String = "" Next i ' outer loop For i=0 to 7 ' set pointer j = i + 1 ptr0 = objS.Sheets(0).getCellByPosition(j,1) ptr1 = objS.Sheets(0).getCellByPosition(j,2) ' calculate index ii = 2 * i + 1 ' inner loop For k=0 To 1 ' get context xstr = ptr0.String If k > 0 Then xstr = ptr1.String End If ' split xlen = len( xstr ) ystr = Right(xstr,7) If xlen = 16 Then xcar = Left(xstr,5) Else xcar = Left(xstr,4) End if xcdr = Left(ystr,4) ' store objS.Sheets(sidx).getCellByPosition(ii+0,k+1).String = xcar objS.Sheets(sidx).getCellByPosition(ii+1,k+1).String = xcdr Next ii Next i End Sub   Calcでは、getCellByPositionでセル位置を相対表現できるので   添字を使って、ターゲットとするセルの右と下をポインタで指定   して扱いやすくしました。  マクロを実行すると、次のように文字列が分割されます。  (項目名は、後から入力しています。)  Excel、Calcのマクロで、セルへ情報を出し入れするとき  大枠からより小さい範囲に絞っていきます。  Calcは、内部でJavaを利用しているのでクラス  インスタンスのメソッドで範囲を狭めていると  考えられます。  ここまでのマクロ定義では、情報が「/」で分けられていると  して扱っています。また、それぞれの情報の文字列長は固定と  して扱っています。  より汎用性のある処理にするため、InStr関数を利用して  書き換えてみます。  Excel   マクロ名を「MySplitX」とします。 Dim xidx As String Dim yidx As String Dim zidx As String Dim xstr As String Dim i As Byte Dim i0 As Byte Dim i1 As Byte Dim i2 As Byte Dim xcar As String Dim xcdr As String Sub MySplitX() ' set pointer sidx = 2 ' clear cells Sheets(sidx).Range("B2:I3").Value = "" ' loop For i=0 to 7 ' set pointer Select Case i Case 1 : xidx = "B3" yidx = "B3" zidx = "C3" Case 2 : xidx = "C2" yidx = "D2" zidx = "E2" Case 3 : xidx = "C3" yidx = "D3" zidx = "E3" Case 4 : xidx = "D2" yidx = "F2" zidx = "G2" Case 5 : xidx = "D3" yidx = "F3" zidx = "G3" Case 6 : xidx = "E2" yidx = "H2" zidx = "I2" Case 7 : xidx = "E3" yidx = "H3" zidx = "I3" Case Else : xidx = "B2" yidx = "B2" zidx = "C2" End Case ' get context xstr = Range(xidx).Value ' split i0 = InStr(xstr,"rpm") i1 = InStr(xstr,"/") i2 = InStr(xstr,"deg") xcar = Left(xstr,i0-1) xcdr = Mid(xstr,jj+1,i2-i1-1) ' store Sheets(sidx).Range(yidx).Value = xcar Sheets(sidx).Range(zidx).Value = xcdr Next i End Sub   BASICでは、文字列の指定位置から部分文字列を   切り出すには、Mid関数を使うのが定石。  Calc   VBAとの差異があるところだけを書き直しておきます。 Dim objS As Object Dim xstr As String Dim i As Byte Dim j As Byte Dim k As Byte Dim ii As Byte Dim i0 As Byte Dim i1 As Byte Dim i2 As Byte Dim sidx As Byte Dim xcar As String Dim xcdr As String Sub Main MySplitX End Sub Sub MySplitX() ' set pointer sidx = 1 ' objS = ThisComponent.CurrentController.ActiveSheet ' clear cells For i=0 to 7 objS.Sheets(sidx).getCellByPosition(i+1,1).String = "" objS.Sheets(sidx).getCellByPosition(i+1,2).String = "" Next i ' outer loop For i=0 to 7 ' set pointer j = i + 1 ptr0 = objS.Sheets(0).getCellByPosition(j,1) ptr1 = objS.Sheets(0).getCellByPosition(j,2) ' calculate index k = 2 * i + 1 ' inner loop For ii=0 To 1 ' get context xstr = ptr0.String If ii > 0 Then xstr = ptr1.String End If ' split i0 = InStr(xstr,"rpm") i1 = InStr(xstr,"/") i2 = InStr(xstr,"deg") xcar = Left(xstr,i0-1) xcdr = Mid(xstr,i1+1,i2-i1-1) ' store objS.Sheets(sidx).getCellByPosition(k+0,1+ii).String = xcar objS.Sheets(sidx).getCellByPosition(k+1,1+ii).String = xcdr Next ii Next i End Sub

目次

inserted by FC2 system