Excel VBA 技術メモ

1Reading Time

Excel VBAの個人的な備忘録ですので、詳しい説明は省略しております。参考URLで詳しく解説されていますので、気になる項目はそちらをご確認ください。

32bit版エクセルと64bit版エクセルのVBA互換について

Sleep関数を使う場合のWindowsAPI関数の宣言

Sleep関数を利用するためには、API宣言Sleep関数を利用しますという宣言が必ず必要です。
WindowsAPIの関数を利用する場合、その宣言を行う必要があります。しかしその宣言方法が32bit版と64bit版とで異なるため、コンパイルエラーが発生します。

そこで、if文で分岐を設け両方のエクセルに対応した宣言を記載します。


#If VBA7 And Win64 Then
  ' 64Bit 版
  Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
  ' 32Bit 版
  Declare Sub Sleep Lib "kernel32" (ByVal dwmilliseconds As Long)
#End If

【説明】

「#If VBA7 And Win64 Then」で64bitの場合の宣言をし、そのほかで32bitの宣言を行っています。

WindowsAPIのSleep関数はVBAで処理を指定時間止める場合に使用します。例えばブラウザのページをVBAで制御していた時に、javascriptの実行を待つ場合などに使用します。

 pwin.execScript "calc()" 'javascriptを実行
Sleep 400 '0.4秒待機

参考URL

VBA 32Bit版と64Bit版でDeclareステートメントの宣言を分ける方法 – Office 2010,2013

VBAで数字を四捨五入、切捨て、切り上げ

エクセルと、VBAで四捨五入、切捨て、切り上げ関数は異なります。

VBAでの関数

四捨五入
value = Application.WorksheetFunction.Round ( expression , decimal_places )

例:小数点1位以下四捨五入

dim x as Double
x = 12.34
MsgBox Application.WorksheetFunction.Round(x, 1)

結果は12.3になります。

切り上げ
value = Application.WorksheetFunction.RoundUp ( expression , decimal_places )

dim x as Double
x = 12.34
MsgBox Application.WorksheetFunction.RoundUp(x, 1)

結果は12.4になります。

切り捨て
value = Application.WorksheetFunction.RoundDown ( expression , decimal_places )

dim x as Double
x = 12.38
MsgBox Application.WorksheetFunction.RoundDown(x, 1)

結果は12.3になります。

VBA の Round 関数

ワークシートのROUND関数は四捨五入ですが、VBA の Round 関数は、最近接偶数丸め又は、銀行型丸め関数です。

銀行型丸め関数は、端数が 0.4のときは切り捨て、端数が 0. 6のときは切り上げ、端数がちょうど 0.5 の場合は、切り捨てと切り上げのうち結果が偶数となる方へ丸めます

例えば、「11.5」の時、「12」にすると偶数になるので、「11」ではなく「12」になります。

半角の「,」を全角に変換

この処理は、CSVファイルなどを出力しないといけない場合に、事前のチェックとして利用できます。ご存知の通りCSVファイルは半角「,」カンマで区切られたテキストファイルですので、セルのデータとして半角「,」カンマが入っているとカラムがずれてしまいます。

そこで、半角「,」カンマを全角「,」カンマに変換する処理をチェック関数の一つに入れておきます。

チェックの方法はセルのデータを一文字ずつ判定して、該当文字があればそれを全角にします。この処理は、例えば全角の数字を半角の数字に統一するなどの処理で応用できます。

Dim wsMain As Worksheet 'メインワークシート変数
Dim x As Integer        '文字x番目
Dim trText As Variant   '変換後の文字列
Set wsMain = Worksheets("Sheet1")

Do While wsMain.Cells(i, 1).Value <> ""      'IDがなくなるまでループ

  trText = ""             '初期化       
  If wsMain.Cells(i, 1).Value <> "" Then
    For x = 1 To Len(wsMain.Cells(i, 1).Value)                '文字がなくなるまで
      If Mid(wsMain.Cells(i, 1).Value, x, 1) Like "," Then   '一文字ずつ取り出して比較
        trText = trText & StrConv(Mid(wsMain.Cells(i, 1).Value, x, 1), vbWide) '全角に変換
      Else
        trText = trText & Mid(wsMain.Cells(i, 1).Value, x, 1)
      End If
    Next x
    wsMain.Cells(i, 1).Value = trText
  End If

i = i + 1
Loop

ちなみに全角の数字を半角に変換する場合は以下のようになります。


  If wsMain.Cells(i, 1).Value <> "" Then
    For x = 1 To Len(wsMain.Cells(i, 1).Value)                     '文字がなくなるまで
      If Mid(wsMain.Cells(i, 1).Value, x, 1) Like "[0-9]" Then   '一文字ずつ取り出して比較
        trText = trText & StrConv(Mid(wsMain.Cells(i, 1).Value, x, 1), vbNarrow) '半角に変換
      Else
        trText = trText & Mid(wsMain.Cells(i, 1).Value, x, 1)
      End If
    Next x
    wsMain.Cells(i, 1).Value = trText
  End If

参考URL:http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_zenkakueisuji.html

ウェブページのスクレイピング

VBAでのスクレイピングについての備忘記録です。ホームページでも解説が少なく苦労した処理などを記載しています。参考になれば幸いです。

読み込むページに要素がなかった場合の処理

要素を読み込む処理は割と解説が多いのですが、読み込む要素がなかった場合の処理は解説が少なく苦労しました。
ページを次々と読み込む処理の場合、ページによっては目的の要素がない場合があります。その時にエラーが発生しないように別の処理に分岐させるものです。

If (doc.getElementsByName("color")(0) Is Nothing) Then    'カラーがなかった場合の処理
      wsPrice.Cells(z, 2).Value = "標準カラー"
end if