開発基本操作
初期設定
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)

コメント