VBA備忘録

開発基本操作

初期設定

VBAではシートの定義をし、シートに対して関数を実行する。

そのため、とにもかくにもまずはシート定義。

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)  '1枚目のシート

イミディエイトウィンドウに出力

Debug.Print val

値の取得

Dim str As String
str = ws.Range("A1").Value

日付など、書式を適用した状態で取得したい場合は.Valueの代わりに.Textを使用する。

ただし、値の比較など行う際に予期せぬ差分が出ることがあるので、あまり推奨しない。

最終列・最終行を取得

空白をスキップして最終を取得する場合(Excel自体の最終列からCtrl+←で最終列を取得する)

ws.Cells(y, Columns.Count).End(xlToLeft).Column '最終列
ws.Cells(Rows.Count, x).End(xlUp).Row '最終行

空白までを取得する場合(特定のセルからCtrl+→で最終列を取得する)

ws.Cells(y, x).End(xlToRight).Column '最終列
ws.Cells(y, x).End(xlDown).Row '最終行

値の検索

Cells.Find("検索文字列")

列から値を検索

Dim r As range
Set r = ActiveSheet.range(“B:B”).Find(What:=”検索文字列”)

コピーペースト

Range("A3") = Range("A1:B2")

コピー

Range("A1:B2").Copy

ペースト

Range("A3").PasteSpecial(xlPasteValues)

PasteSpecialにオプションを指定することで、何をペーストするかを指定できる。

Range("A3").PasteSpecial(xlPasteValues)  '値貼り付け
Range("A3").PasteSpecial(xlPasteFormats)  '書式貼り付け
Range("A3").PasteSpecial(xlPasteAll)  'すべて貼り付け

オプション指定しないと、xlPasteAllの挙動になる。処理がかなり重たくなるので、基本的には必ずxlPasteValuesオプションを付与する。

行コピー

ws.Rows(2).Copy '2行目をコピー
Rows(3).PasteSpecial(xlPasteValues)

挿入

行を挿入

ws.Rows(2).Insert '2行目に行を挿入

CellsとRangeの切り替え

Range→Cells

Cells(ws.Range("A1").Row, ws.Range("A1").Column)

Cells→Range

Cells(1, 1).Address '"$A$1"
Cells(1, 1).Address(False, False) '"A1"

セルの削除

特定行以下のセルをすべて消去・削除

'5行目以下を削除する
ws.Rows(5 & ":" & Worksheets("Sheet1").Rows.Count).Delete

重複削除

ws.Range("A:A").CurrentRegion.RemoveDuplicates Columns:=1, Header:=xlYes

1行目にヘッダーが存在しない場合はHeader:=xlNo
1行しかない場合エラーになる可能性がある

フィルター

Range("A1:C6").AutoFilter 1, "*.png" '末尾が『.png』で終わるもの

Excel自体のフィルター機能を利用している。
その性質上複数条件を設定するのは向いていない。

フィルターの解除

Range("A1:C6").AutoFilter '引数なしで使うと解除

型判定

VarType(val)

シート名のカウントと一覧出力

■カウント

任意のセルを選択 > =sheets()

■一覧出力

VBAのイミディエイトウィンドウを開く(Alt + F11 > Ctrl + G)

以下を入力してEnter

For Each i In ThisWorkbook.Sheets: debug-print i.name : next i

設定

どこから起動する?

ナビゲーションバーの開発タブ。開発タブが無い場合は以下から有効化する。

ファイル>オプション>リボンのユーザー設定
『開発』を有効化

ソースコードはどこに書く?

以下からモジュールを新規作成し、開発を始める。

ナビゲーションバーの『挿入』>標準モジュール

インシデント

マクロが無効のエラー

エラーメッセージ:セキュリティ上の理由から、エンタープライズ管理者がこのドキュメント内のマクロを無効にしました。

対象のマクロを含むエクセルを右クリック>プロパティ>全般タブの最下部に表示されるセキュリティメッセージで『許可する』にチェックを入れる

※以降、プロパティを開いても、このセキュリティメッセージは表示されなくなる

■Nextに対応するForがありません。
For文の中のEnd Ifがない
■中断モードでコードを実行することはできません
アドオンのせいっぽい
https://qiita.com/thakaz/items/113c689ea9e8fed3080b
エラーメッセージの非表示
コンパイルエラー
自動構文チェックを無効化する
ツール> オプション >自動構文チェック

文字列の置き換え
Replace (対象文字列, 検索文字列, 置換文字列)
ただ、めちゃ重い
Excel VBA Replace 関数で文字列を高速で置換する方法と速度検証

vba コメントアウト ツールバー 無い
表示> ツールバー > 編集

■セルに関数を設定
repoSh.Cells(i, 3).Formula
= “関数 “
動的に作れないが、 頑張って文字列を&でつなげて関数作るしかない

■URLを開く

endRow = sh.Cells(Rows.Count, TARGETCOL).End(xlUp).Row  // 最終行

Dim targetVal As Variant
For i = HEADROW + 1 To endRow
  targetVal = sh.Cells(i, TARGETCOL)
  sh.Hyperlinks.Add(Anchor:=sh.Range("A1"), _
    Address:=targetVal).Follow
Next i
sh.Range("A1").Delete

■文字列、 含む: instr
instrは文の中の検索文字列の位置を返す
文字列が存在しない場合は0を返す。
instr(文, 検索文字列)
文字列が存在しない場合は0を返すので、IF文で分岐できる
if instr(文, 検索文字列) Then

■全角を含むかどうか
・文字列が存在すればTrue、存在しなければFalesと同じ扱いになる
Len(targetVal) <> LenB(StrConv(targetVal, vbFromUnicode))

■全セル消去
[ShName.]Cells.Clear

■Forを逆順にする ※空白行削除

For i = lastRow To firstRow Step -1 // 最終行を先に指定する点に注意
  If sh.Cells(i, TARGETCOL) = "" Then
    'A列が空白なら行削除
    Application.Rows (i).Delete
  End If
Next

■日付
Year(Date)
Month (Date)
Day (Date)

■テキストファイルの読み込み (UTF-8対応、1行ずつ)

filepath = "C:/…/import.txt"
With CreateObject("ADODB.Stream")
  .Open
  .Charset = "UTF-8"  // BOMあり、BOMなし両対応
  .LineSeparator = -1'-1=CRLF
  .LoadFromFile filepath
  '1行毎に処理
  Do Until .EOS
    TextLine = .ReadText(-2)  // 1行取り出す
    // 処理‥‥‥‥
  Loop
  .Close
End With

■CurDirは要注意
カレントディレクトリの初期値はOSでは一般的に\User\Documentを指す。

■For文のループ回数、 endを可変にしたい
Step -1 で後ろからやる

■Nothing判定
If target is nothing then

if not target is nothing then

■Rangeオブジェクトが勝手にString型になる
> 参照だから評価後の値になるため自然な挙動。

■オブジェクトが必要です、エラー

Dim a As Range
Set a Range(“A1”)
sampleSub(a)  // エラー

> Callを忘れている。
Call を付けないとFunctionとして戻り値を求められる。
その戻り値を格受け取るオブジェクトが無いというエラー。
Call sampleSub (a)

 

 

 

 

コメント

タイトルとURLをコピーしました