見出し画像

エクセルマクロのワザ

わたしはエクセルマクロの本は持っていない。
以前は知りたいことを書店で立ち読みしながら物色したこともあるが、欲しい情報がきっちり手に入る本はなかった。本の情報は広いが浅い。
それより、ネットで調べたほうが遥かに質のよい情報を大量に手に入れることができる。ネット上には「そこそこ、そこが知りたかったんや」という痒いところに手が届く情報がそこらじゅうに転がっている。苦労して辿りついた知識やワザを惜しげもなく提供される天下一武道会の方々がおられる。感謝しかない。
以下にネットで得て重宝したいくつかのワザを記録として残す。

1 図形の表示
図形のコピペは①コピー(OSの機能)→②ペースト(VBAの機能)の手順だが、①より②の処理の方が速いのでPCのスペックによってはエラー(104)が出ることがある。2つの処理の間にsleep timeを取る方法もあるが、コピペの回数が多い時はストレスが溜まるくらいの遅延になる。

'sheet[en]の図形"shape_A"をセルA2にコピペする
With Worksheets("en").Shapes(shape_A).Copy 
    Sleep sleep_time                   'Copyを確実に終わらせてから、Pasteを実行させる
    ActiveSheet.Paste                  'Paste
    Selection.Left = Range("A2").Left  '位置の指定
    Selection.Top = Range("A2").Top
End With

これを避けるには、同じシート内の見えない領域に図形を貼り付けておき、その図形を移動する方法がある。これだとストレスは溜まらない。

'sheet内の図形"shape_A"をセルA2に移動する
ActiveSheet.Shapes(shape_A).Left = Range("A2").Left 
ActiveSheet.Shapes(shape_A).Top = Range("A2").Top

2 特定の値群からのランダムな抽出
配列にデータを入れておき、ランダムに選んだ配列番号から配列データを参照するとよい。

Dim i As Integer
Dim n() As Variant
Dim n As Integer
n = Array(0, 3, 6, 7, 9)  'データを配列に格納
Randomize
i = Rnd * (5 - 1)         '0-4までの乱数発生
num = n(i)                '該当する配列のデータを参照

3 配列へのデータの格納
マクロの中で定義すると、データ数が多い時のデータの変更は非常に煩雑である。
シートに作ったデータの表を読み込む方法がある。これだとデータのチェックや変更が簡単である。(ただし、この方法は配列番号が0ではなく1から始まるので注意すること)

Dim Data As Variant 'データを格納する配列

Sub a()     '[Sheet1]のセル範囲(C4:F6)を読み込む
    Dim i As Integer
    Data = Worksheets("Sheet1").Range("C4:F6").Value 
    
    For i = 1 To 3
        Debug.Print Data(i, 1) & " " & Data(i, 2) & " " & Data(i, 3) & " " & Data(i, 4)
    Next    '出力結果   C4 D4 E4 D5
            '           C5 D5 E5 D5
            '           C6 D6 E6 D5
End Sub

4 DoEventsの連打
For Nextを使ってセルの値を順次入れ替えて、その値を反映してグラフをアニメーションさせようとしたら動かない。グラフが動くようになるまでFor Nextの中に「DoEvents」を連打連打連打。。

Sub graph_animation_1()
    Dim i As Integer
    wait_time = 500
    init_position = -5
    For i = 1 To 11
        Range("B6").Value = init_position + 1 * (i - 1) '初期位置
        DoEvents: DoEvents: DoEvents: DoEvents  '連打連打連打。。グラフが動くまで
        Application.Wait [Now()] + wait_time / 86400000
        Debug.Print i
    Next i
End Sub

いいなと思ったら応援しよう!