by h-fuji

ちょっと、メモがわりに。
<EXCEL97>

VBA画面(excel97)

[初歩のはじめ] | [サンプル(ダウンロード)] | 「〜をするには」のモジュール例 | [ Excel VBA Memo へ ] | TopPageへ |  
                                    


_

■ 初歩のはじめ
(1) VB_EDITORを開く: 表示(V) 〜 ツールバー 〜 VisualBasicEditorを選択。 または、ツールバー上で右クリック〜VisualBasicを選択。
       エクセルウインドウとは、別にVBのウインドウが開きます。画面下部のタスクバーにエクセルとVBEの2つがあることになります。
       VBEのウインドウを閉じても、エクセルは終わりませんがエクセルを終了すると、VBEのウインドウも閉じられます。

       これから作成するマクロ(VBA)は、そのブックに含まれます.(マクロの保存場所は、ブック内です。)
(2) 挿入(I)〜標準モジュールを選択.
    VBA画面

    □ Book1-Module1(コード)のウインドウ内に、手続きを記入して、マクロを作成していきます。
       まず、やることはマクロの名前を記入します。
       SUB TEST( )

       ※ SUB は決まりごと。その次の「TEST」がマクロの名前.何でも、自分に分かりやすい言葉を付けることができます。
          最後の( )も、決まりごと。マクロの名前には、漢字も使用可能。でも、お勧めは、英字。 

       SUB TEST() と入力して、enterキーを押すと、自動的に END SUB が下に追加される。
       ----------------------------------
       SUB TEST()
        '
       END SUB
       ----------------------------------
       
       SUB TEST()とEND SUBの間に、マクロを定義する。
       ----------------------------------
       SUB TEST()
        '
        range("a1")=5*range("b1")    ' B1セルの値に5倍した値がA1に代入されます。
       END SUB
       ----------------------------------
       「END SUB」の下に、SUB TEST1() と入力すると、「END SUB」と「SUB TEST1()」の間に、罫線が自動的に
       引かれます。 


      ■ とりあえずは、やってみるということで。
       モジュール・ウインドウ内に、以下のように入力します。

       sub 数を入れる()    ' <-- 数を入れる というマクロ名になる
          Range("a5")=12   ' <-- 手続き
       end Sub             ' <-- マクロの終了

       そのままの状態で、エクセルウインドウをアクティブにします。
       ツールバー上にマウスポイントを置いて、右クリックしてツールバーメニューからフォームを左クリックします。
       シート上にフォームのツールバーが表示されるので、その中からボタンをクリックします。

       シート上で左ボタンを押したまま、ボタンの大きさを決定します。
       適当な大きさで左クリックを離すと、マクロ登録ウインドウが表示される。先ほど、記述した 数を入れる という
       マクロ名があるので、それをクリックで選択してOKボタンをクリックします。 <--- これでボタンとマクロの関連付けが完了。

       ボタンの中で、カーソルが点滅するので、ボタンの名前を入力します。
       今はテストですから、そのままでもOKです。ボタン以外のシート上のどこかで、クリックするとボタンが確定します。

       では、ボタンを押してみましょう.
       A5のセルに 12が入りましたか?

       OKなら、次に、VBEのウインドウに切り替えます。(タスクバーにあるVBEをクリックして、VBEウインドウをアクティブにします。
       Range("A5")=12 を Range("A5")=Range("a3")+range("a4") に変更します。
        ※ 英文字の大小はどちらでもOKです。VBEが勝手に,変更してくれます。

       シート上のボタンとVBAである 数を入れる()とのリンクはそのままなので、
       セルA3とA4に適当な数を入れて,ボタンを押します。
       A5セルに、乗算の結果が表示されましたか?  あとは、想像力次第かな!?(^^/

     ■ 条件に応じていろいろ処理を自動化する とか 繰り返しは機械にさせる ことができると、
        いかにもパソコンを操っているという、ちょっといい感じがします。 

        if文: if関数に似ているので,すぐにわかりますね。
                                          *もし、セルA3が4だったら、セルB5に、セルA5×5の値を代入する。
                  (例)
                                               IF RANGE("A3")=4 THEN RANGE("B5")=RANGE("A5")*5
                                          *もし、セルA1の値が1だったら、モジュール1の処理1マクロを実行し、
                   セルA1の値が1以外だったら、モジュール1の処理2マクロを実行せよ。
                  (例)
                  IF RANGE("A1")=1 THEN
                                                         MODULE1.処理1
                  ELSE
                      MODULE1.処理2
                  END IF
        case文: 条件に応じて、複数分岐して処理を行わせることができます。
        for〜next文: 繰り返しは,この文を使います。
                *A列の1行から10行まで、連番を付ける。
                  dim i as long           ' i という変数を使用するという宣言
                                              for i=1 to 10    ' i は1から始まり,10になると、繰り返しを終了する。
                                                    range("a"&i)=i  ' 繰り返す内容(処理)
                                              next          ' i に1を加算して、forに処理を戻す。

        操作をどんどんやっていくと、どの機能を使うと、どのようになるのかが推測できるようになります。
        そして、機能の組み立てが推測できるようになると、より効果的なマクロが組めるようになります。

        例: ホストデータを、外部プログラムをshellで実行して、csvファイルに落とし込み、エクセル表にし、
           ピボットテーブルで、集計単位を一意データにし、そのピボットテーブルをテキストに複写して、
           出来あがっている出力表に、VLOOKUPで必要な列を貼り付ける。

        このような通常操作を出来るだけ詳しく文書化して、その一つ一つの処理をマクロに置き換えていくと、
        定型的な処理の自動化ができます。

        ■ しかし、実際に「形」のある(起承転結のある)マクロを作ろうとしたときは,VBAの技術的なこととは、
          別に、業務の「流れ」というものを理解していなければなりません。さらに、その業務(仕事=作業)を
          EXCEL+VBAでどのように置き換えるかの「想像力」が必要となります。
           たとえば、家計簿というものをエクセル+VBAで作ろうとした場合, いつ、どのデータをもとにして、
          (通常、この場合だと、レシート+普通預金通帳などでしょうか)だれが入力して、何を「管理」したいかを
          明確にしておく必要があります。家計簿が欲しいと思いながらも,実際は資金管理がしたかったりして、
          せっかく費用の使途がわかり、削減できるものとそうでないものがわかっても、あまり評判がよくなかった
          りします。


    マクロ化すると・・・
    ☆ 手順が長い表作成などを行う場合は、マクロ化(ボタンで処理が始まる)しておくと、非常に楽になる。
       作成するのが大変ではありますが。たとえば、ホストからのデータを取得して、分析表などを作成する場合など。
       *データシートにフィルターをかけて、その結果をピボットで分析し、ピボット結果に、VLOOKUPで値貼り付けし、
        印刷プレビューまでを自動化したり、グラフ表示までを自動化したりできます。

    ☆ 入力用の表(入力画面)とデータベース用の表(フィルターやビボットテーブルが利用しやすいような表形式)を
       別にすることができる。〜 データを貯めこむシートとそれを元に分析する手順を分けることができる。
       
    ☆ 計算式ではなくて、マクロでその値のみを代入すると、表が必要に以上に大きくならない。


● キー記録を理解して、汎用化する。

   と言う前に、基本文
   セルA1の値をC1に貼り付ける。
   キー記録だと、

   Range("A1").Select
   Selection.Copy
   Range("C1").Select
   ActiveSheet.Paste
   Application.CutCopyMode = False
   Range("C3").Select

   となるが、

   (1)=(イコール文)
   VBAでは、
   range("C1").value = range("A1").value
   range()は、セルに読み替え。
   =(イコール)文は、右の値が左に代入される。

   セルA1というとき、前提として、シートがアクティブになっている
   わけで、シート名をクリックする場合、VBAでは、
   sheets("sheet1").activate
   とする。

   何気に行っている操作を、VBAでは指定する必要がある。
   VBAでシート指定をしない場合は、アクティブになっているシートに
   対して処理が実行される。

   シートAAAのセルA1の値をシートBBBのセルC1にコピーするなら、
   sheets("BBB").range("C1").value=sheets("AAA").range("A1").value

   workbooks("a").sheets("BBB").range("C1").value=workbooks("B").sheets("AAA").range("A1").value
   とすると、
   ワークブックB.xlsのシートAAAのA1セルを、ワークブックa.xlsのシートBBBのC1セルに代入する。
   前もって、ブックa.xlsとB.xlsをオープンしておくことが必要だけど。


   (2)for〜next文
   =文のほかに、繰り返しを憶えるといい。

   dim i as long
   for i=1 to 10
        range("a" & i).value=i
   next

   for 〜 nextが繰り返しの基本。
   iは変数
   dimは変数定義をすること。
   longは変数の型。数値とする。
   文字型にする場合は、dim i as string とする。

   これを実行すると、
   A1からA10までのセルに、数字が順番に1〜10代入される。

   上の他シートへの代入(コピー)の場合であれば、
   dim i as long
   for i=1 to 10
   sheets("BBB").range("C" & i).value=sheets("AAA").range("A" & i).value
   next
   iは行番地の変数となっている。


   (3)if文
   if range("c1").value > 0 then
      range("c1").value=range("a1").value * 10
   else
     range("c1").value=range("a1").value
   end if

   基本文はこのようになる。
   if 条件式 then
     条件が合致した場合の処理を記載
   else
     条件を満たさない場合の処理を記載
   end if

   で、先ほどの文は、C1セルの値が正の場合は、
   A1セルの値を10倍して、セルC1に代入し、
   そう出ない場合は、
   A1セルの値をそのまま、セルC1に代入する
   となる。


   (4)キー記録の汎用化
   VLOOKUP関数をセルに代入するマクロです。

   Range("D1").Select
   ActiveCell.Value = "=VLOOKUP(C1,$A$1:$B$12,2,0)"
   Range("D7").Select

   下記のようになった場合は、
   ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-1],RC[-3]:R[11]C[-2],2,0)"
   相対座標で記録されたので、これではわかりづらいので、
   これを上のように、
   ActiveCell.Value = "=VLOOKUP(C1,$A$1:$B$12,2,0)"
   とします。

   最終行が可変である場合が多いので、vlookupの参照先の行数を変数にします。
   上の式では、b12までの範囲でしたので、この12行を変数にして、マクロ内で
   行数を設定できるようにします。

   sub macro1()
       dim i as long
       Range("D1").Select
       i=20
       ActiveCell.Value = "=VLOOKUP(C1,$A$1:$B$" & i & ",2,0)"
   end sub

   セルD1の内容が、=VLOOKUP(C1,$A$1:$B$20,2,0) と変わっているのを確認。

   これで、VLOOKUP()関数を使った場合に、参照先のデータ増えても対応できることに
   なります。

   参照先の最終行=B列の最終データ行の取得は、
   gyou = ActiveSheet.Range("a65535").End(xlUp).Rows
   又は、
   gyou=ActiveSheet.Range("a1").currentregion.rows.count
   などを利用して、最終行番号を取得します。
   この場合h、gyouという変数に最終行番号が代入されます。

   gyou = ActiveSheet.Range("a65535").End(xlUp).Rows は、
   セルa65535から、ctrlを押したまま上矢印キーを押した時に選択されるセルの
   行番号がgyouに代入されます。

   gyou=ActiveSheet.Range("a1").currentregion.rows.count は、
   a1セルを選択した状態で、ctrl+shift各キーをおして、*キーを押した場合の
   領域の最終行番地がgyou変数に代入されます。




 TopPageに