イミディエイトウィンドウ内で一時的に使う変数

イミディエイトウィンドウ内では変数の宣言は必要無い。 バリアント型なのでどんな型やオブジェクトでも使える。

もし、標準モジュールのGeneral-Declarationsに書いたPublic宣言した変数名をイミディエイトウィンドウで使うとイミディエイトウィンドウで新たに作ったヴァリアント型の変数ではなく、その宣言した変数で、型もその型になる。標準モジュールにPublic宣言した変数名とは違う名前を使うとバリアント型のイミディエイトウィンドウ内で使える変数になる。

適当な名前を入れるとバリアント型の変数として使える。以下はイミディエイトウィンドウ。

?aaaaa
         '初期値のままなので空白
?vba.TypeName(aaaaa)
Empty                 'バリアント型の初期値はEmpty
dd=123  'dd変数に123という数値を入れる
?typename(dd)
Integer
?dd+2    '計算する
 125     '計算結果 
dd=1.3
?vba.TypeName(dd)
Double
?12a+1    '入力ミスだが、何とかPrintする
 12  1 
?1+12a    '先頭が数字があると数値にして計算する
 13 
aaa="abc"    '文字列は、””で囲む。aaaは変数。
?aaa
abc 
?aaa & "ccc"
abcccc
?aaa & 111
abc111
?aaa + "1111"
abc1111

数値は、そのまま入力、文字列は””で囲む。用語として文字は1文字、文字が複数連続して並ぶと文字列という。また、数値とは演算対象になる、数字は1から0までの文字のことをいう。

カテゴリー: 3 習熟のためにイミディエイウィンドウを使う | コメントする

マクロ記録のコードの特徴と修正のポイント

マクロ記録は、ユーザーの操作をそのまま記録しようとする。これを実現するために、ActiveとかSelectなどユーザーが選んでいるオブジェクトを使う。Excel本体を動かすとApplication。よく見るのはActiveCell、Selection、ActiveSheetなどがある。これらのオブジェクトは、どれもApplicationオブジェクトの直下にある。オブジェクトブラウザのグローバルなメンバーです。

マクロ記録では、Application直下というかグローバルなメンバーが使いやすいでしょうね。

VBEでF2。オブジェクトブラウザのExcelライブラリのグローバルなメンバー

さて、マクロ記録の結果の一部ですが以下は変換/修正しやすい。

  1. ActiveSheet:Worksheetクラス(型)
  2. ActiveCell:Rangeクラス(型)

ActiveSheetは、Sheet1やSheet2に変える
ActiveCellは、Sheet1.Rnage(“??”)やSheet1.Cells(2,4)のように変える。

しかし、

Selection:Objectクラス/型(オブジェクトの型なら何でもSetできる汎用的なクラス/型)

SelectionはObject型なのでどんなオブジェクトでも私達がマウスであるものを選択すればそれがSelectionとして使えるのでマクロを記録するシステムからすると利用範囲が広い。だから、マクロを読む場合は、何を選択したか流れを読む必要がある。例えば、以下はマクロ記録の一部。行を選択して削除(行削除)をしている。

    ActiveCell.Offset(3, 0).Rows("1:1").EntireRow.Select
    Selection.Delete Shift:=xlUp

この場合は、Selectionは、.EntireRow.Selectで行を選択していることがわかる。つまり、Selectionは前の行でSelectしているオブジェクトをチェックする。

記録したマクロ/Macro1()を以下の手順で修正する。

  1. 欲しいメンバー(プロパティやメソッド)を探す
  2. そのメンバーを持つオブジェクトが修正の対象になる
  3. どんな流れでそのオブジェクトを取り出すか手順を探す
  4. 記録したマクロのコードをメモ帳にコピーしておく
  5. Macro1()などのコードを修正してF8(デバッグのステップイン)で動作を確認する
  6. 引数を追加して汎用的に使えるようにする。
カテゴリー: 4 マクロ記録でオブジェクトを調査する | コメントする

マクロ記録だけですぐに使える例

「相対参照で記録」を使うとマウス操作で同じ繰り返しの作業が記録できるのでそのまま使える。

例えば、A1のセルのデータを1行おき下にコピーする。

カテゴリー: 4 マクロ記録でオブジェクトを調査する | コメントする

マクロ記録を見るコツ

仕事のすき間?。ちょっと繰り返しが多いし、単純なんで間違いそう。という処理はマクロ記録で繰り返したい。動画もマクロ記録を中心と考えていたが結構、マクロ記録できない部分ばかりを書いている。

いろいろ知っているので書きたいでしょうね>自分へ

私のマクロ記録は、だんだん少なくなっている。それはいろいろ経験して覚えたんだろうな。仕事は記憶しない、メモ、テプラーで手順を貼る、私の考えだが、慣れて記憶する。仕事は、高校までの学習とは違います。苦労したらいい仕事はできない。

当初、マクロ記録があることで「ニヤ」っとしたなー。だって、プログラム言語ってライブラリを使ってやって仕事ができるんです。新しいライブラリを使う場合は本や、私の場合は使いまくる。調査時間がかかるんです。でもExcelやOffice製品は操作を記録できるのでね!!ワオ。うれしい。

私の場合は、VisualBasic(VB)を使っていた。だから、VBAの仕様はわかっており、コードも書ける状態から初めた。マクロ記録は、Excelのオブジェクトを調べるためだった。ヘルプで探すより早いもんね。2000年ごろかな?。インターネット上にも情報は少ない。だからマクロ記録で調べる。現在は、ネットで検索する方が早いかもしれない。

とこで、「VBAの言語が先か?」という話しでは無い。ベースとしては言語仕様は変数、引数、プロシージャーの作成、Do Loop、For Eachの繰り返しができれば十分。というか、Excelオブジェクト無しにVBAのコードを書くことは無い。ので、同時進行。仕事の合間にするもんだからね。このサイトでは、「 Excelオブジェクトの説明が多い場合は<E>。VBAの言語の説明が多い場合は<VBA> 」と目次に書いてあるので、これを参考に必要に応じて見て下さい。まだまだ完成しませんが。

マクロ記録を見ながらだが、だいたい、前と最後に注目する。まずは、最後のプロパティとメソッド。要求したタイミングのプロパティやメソッドをチェック。そして、その親のオブジェクト。そのオブジェクトが出てくるながれかな。以下が箇条書きに。

  1. そのオブジェクトのプロパティ、メソッド(要求内容)
  2. どのオブジェクトで求めることをしているか
  3. そのオブジェクトが現れるタイミング。親子関係。

生、ライブでマクロの記録を見るコツです。また、不要なコードはどんどん消しましょう。メンタル的にあちこちに目がいって集中できない。

カテゴリー: とりあえず | コメントする

スタック領域とは (深い話し)

上図のエラーメッセージを見たことがあるでしょうか?。「スタック領域が不足しています。」とは何なん?。再帰呼び出しのプロシージャを作らないと見ることも無いと思います。

以下のようなコードを標準モジュールかSheet1などのモジュールに書いaまたはbのプロシージャを実行すると上図が現れる。

Sub a()
    b
End Sub

Sub b()
    a
End Sub

この例では永遠に相手を呼び出すためスタックを使い果たす。で、「スタック領域」ですがC言語では説明が必ずあります。「ヒープとスタック」Googleですが、再帰呼び出しを理解する時に必要です。ヒープはある領域を確保、解放できる自由なメモリ領域。その領域をスタックとして使う。

別のコードを示す。mainを実行するとaプロシージャを呼び出し、aプロシージャのEnd Subを抜けると呼び出し元であるmainプロシージャに戻り、mainプロシージャのEnd Subで終了する。

Sub main()
  a 1, 2  
End Sub

Sub a(引数1 As Integer, 引数2 As Long)
  Dim ii As Long 'ローカル変数。aプロシージャ内で有効な変数。プロシージャレベルの変数
End Sub

プロシージャの呼び出しはスタック領域を使う決まりになっている。コンピュータの演算装置/CPUの仕組みとしてもスタックポインタという高速にメモリ番地を入れるレジスタ(箱のような物)がある。スタック領域は、メモリ上にある深い箱のようなものでメモリの番地を指す機能を持つ。スタック領域の構造は先入れ後出し法の深いツボの形Google。反対のキューの構造は、先入先出法のパイプの形。

プロシージャの呼び出しは、以下の2つのことをしてプログラムが動くことを気にして下さい。

  1. 実行位置をたどり、書いてあるコードを処理する。処理自体が実行位置を進むこと。
  2. 個々のプロシージャの処理コードは、あるメモリ領域にあり、プロシージャー間で呼び出す場合は、呼び出した所に戻るための位置や複数の引数、そのサイズをプロシージャーの定義(Sub/FunctionからEnd Sub/Functionのこと)、引数の通りにスタックに積み、呼び出されらたプロシージャーは、スタックから引数の順に取り出す。

Sub main()がaプロシージャを呼び出す時に、引数に1,2に渡すが渡すとはスタックに積むこと。引数1が引数2の半分の大きさにしているのは引数1はInteger型、引数2はLong型のため。さらにaプロシージャ内で宣言したii変数もスタック上に作られ、aプロシージャの処理が終わるとスタックポインタは「リターンアドレス」呼び出し元であるmainのコード上のaプロシージャを呼び出した位置(アドレス)に処理先を戻す。

前のコードの場合は、aプロシージャーを呼び出したらmainプロシージャーに戻るのでスタックオーバー(スタック領域が不足しています。)にはならない。

次のコードは、aプロシージャーは内部でaプロシージャーを呼び出す、「再帰呼び出し」をしている。aプロシージャーのコードは、aプロシージャーが終わる、抜ける分岐処理をしていないためスタック領域を使い果たす。

Sub main()
  a 1, 2
End Sub

Sub a(引数1 As Integer, 引数2 As Long)
  Dim ii As Long 'ローカル変数。aプロシージャ内で有効な変数。プロシージャレベルの変数
  a 11, 22 '自分自身を呼び出す。再帰呼び出しでスタックにデータは積むが取り出すことは無い
End Sub

再帰呼び出しは、同じ名前のプロシージャーだが引数やプロシージャー内でDim宣言した変数は、呼び出す度に違う引数、変数です。スタック上で使いますわす事は無い。これがあるから再帰呼び出しで同じ処理だが、引数や変数が違うのでそれぞれで適切な処理ができる。

ある仕事をする処理する単位は、プロシージャと言えます。クラスという巨大化した変数の前にプロシージャー間のインターフェースは知るべきです。ただ、RubyやPythonなどはクラスを作るところから始まることが多いが、RubyやPythonでもVBAで言うプロシージャが使えるだけで十分に仕事はできます。

クラスのプロパティやメソッドが使う側のインターフェースであるように、スタックは呼び出す側と呼び出される型のプロシージャとのインターフェースです。クラスうんぬんの前に知るべき機能です。

なお、プロパティやメソッドの呼び出しにもスタック領域は使います。

カテゴリー: 13 ファイル処理、メモ帳とのデータ処理 | コメントする