3/2の入力を次年度の入力にする

イベントの活用例です。

セルに年を入れず、「月/日」形式で入力した場合、年を省略しているためその年の月日になる。例えば、今年が2000年の場合「2/3」とセルに入力すると「2000/2/3」になる。年度で入力したい場合は、1月から3月までは次の年になるように、イベントプロシージャを設定する。

Private Sub Worksheet_Change(ByVal Target As Range)
    If IsDate(Target.Value) Then
        Debug.Print "日付だ"
        Select Case Month(Target.Value)
            Case 1, 2, 3
                Excel.Application.EnableEvents = False '次行でWorksheet_Changeイベントが何度も発生しないようにする
                Target = VBA.DateSerial(Year(Target) + 1, Month(Target), Day(Target))
                Excel.Application.EnableEvents = True '解除
        End Select
    End If
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

は書きません。オブジェクトボックスをWorksheet。プロシージャ/イベントボックスでChangeを選ぶと勝手にモジュールに入る。動画またはこちらで確認下さい。

もう一つ。活用例。

「ぺけ」の形の文字は、いくつかある。これをイベントプロシージャを使って黄色の塗りつぶしのセルで「ぺけ」に似た文字の場合は、半角の小文字のx(エックス)に変える。

x,X,x,X,× 。順に、半角の小文字、半角の大文字、全角の小文字、全角の大文字、乗算記号。

Private Sub Worksheet_Change(ByVal Target As Range)
    If 1 = Len(Target) And Target.Interior.Color = VBA.vbYellow Then '1文字で黄色の塗りつぶしの場合
        Select Case Target
            Case "x", "X", "x", "X", "×"
                Excel.Application.EnableEvents = False
                Target = "X" '半角大文字X
                Excel.Application.EnableEvents = True
            End Select
    End If
End Sub

カテゴリー: 14 イベントの使い方 <VBA> | コメントする

エクセルでBATファイルを作って実行

makeabc.batを例に以下のことを実行します。

  1. VBAのカレントフォルダを変更する(作業フォルダ)
  2. Excelのシートに書いたBATファイルを保存する
  3. 保存したBATファイルを実行する VBA.Shell関数
  4. BATファイルを取り込む、読み込む。書き込み。

なるべくマクロ記録して、修正やイミディエイトで確認しながら作っていきます。コマンドプロンプトの実体cmd.exeやそのexeファイルの中で持っているコマンドcopyやmkdirの話し(cmd.exeが持っている?Excelと対比すると、Exceが持っているコマンドとはメニューのこと)もします。cmd -hも

VBAのMkDirやFileCopy関数でもできますが、VBAの関数の場合は、以下のエラー。「実行時エラー75:パス名が無効です。」翻訳すると「すでに同じフォルダやファイルがありますので作れません。」です。

一方、BAT。つまり、コマンドプロンプトの実行というかcmd.exeのコマンドはエラー無しにできることだけをします。ええ感じです(上書きは注意しないといけまんが)。

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

ListObject

メニュー/挿入/テーブルにするListObjectが使えるようになる。Accessのデータセットと同じように使えないかしら?

こっちが詳しい素晴らしい m(_ _)m (また帰って来てくださいね)。

これ結構深いのでまた追記します。

カテゴリー: 12 ExcelのVBAを快適に使うためのアイデア <E> | コメントする

VBAでファイルのコピー、フォルダ作成

ドキュメントにフォルダaaを作り、aaの中で以下のことをします。

  1. ファイルのコピー  FileCopy
  2. フォルダの作成   MkDir
  3. フォルダの中にファイルをコピー FileCopy
  4. ファイル名の変更  Name As
  5. ファイルの移動   Name As
  6. ファイルの削除   Kill (復活不能、ゴミ箱に入らない)
  7. フォルダの削除  RmDir

エクスプローラーを起動して、VBAの関数の実行結果を確認します。

DirコマンドといえばMS-DOS。1990年ごとバブル景気の最後のころです。そのころにVBAでもDOSコマンド相当の関数が提供されました。

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

配列数式で転記。その2。Ubound(a,b)

その1では、必要な行のデータを転記する例でした。次は、2つの表から1つの表を作る方法を説明します。

その1で作った配列は、そのまま引数arGouとして使う。セルの範囲を指定をする引数rAddressは、受講台帳のデータ範囲を指定する。変数名のarやrは、arはArray配列、rはRangeの意味で付けてます。

'合格者の配列と受講台帳のセル範囲で照合する
Function myAddr(arGou, rAddress As Range)
    Dim ar() 'Rangeの範囲のデータを入れる動的配列
    ar = rAddress 'こちらは全部の値をチェックする
    Dim i As Integer, j As Integer, k As Integer
    j = 1 'For文の中で使い始めで0だと飛ぶため。
    ReDim arr(1 To UBound(ar, 1), 1 To UBound(ar, 2)) 'データ以上になることは無い
    Dim iii As Integer 'arrの行番号用、列はjを使う
    For i = 1 To UBound(ar, 1) '2次元配列の1番目、行。1から始めるのはrがRangeだから
            For k = 1 To UBound(ar, 1) 'iの各行に全arGouの名前と照合するために繰り返す
                If arGou(i, 2) = ar(k, 4) Then 'arGouの2列目とarの4列を比較
                iii = iii + 1 'スタートが1なので先に1にしておく
                    For j = 1 To UBound(ar, 2) '2次元配列の2番目、列
                        arr(iii, j) = ar(k, j) 'iではなくk
                    Next
                End If
            Next
   Next
   myAddr = arr
End Function
'=myAddr(myGoukaku(テーブル3),テーブル12)

その1のmyGoukakuで合格者だけの2次元配列、myAddrで降格者だけの受講台帳の2次元配列を作ることができた。では、この2つの2次元配列を使って合体させるのがmyTennkiです。

'2つの2次元配列から転移目的の関数の完成です
Function myTennki(arTest, arAddress)
    Dim i As Integer, j As Integer, k As Integer
    If UBound(arTest, 1) > UBound(arAddress, 1) Then
        i = UBound(arTest, 1)
    Else
        i = UBound(arAddress, 1)
    End If
    If UBound(arTest, 2) > UBound(arAddress, 2) Then
        j = UBound(arTest, 2)
    Else
        j = UBound(arAddress, 2)
    End If
    ReDim arr(1 To i, 1 To j) '2つの引数の最大でメモリを確保
    j = 1 'For文の中で使い始めで0だと飛ぶため。
    Dim iii As Integer 'arrの行番号用、列はjを使う
    For i = 1 To UBound(arTest, 1) 'rTestの方の行処理
            For k = 1 To UBound(arAddress, 1) 'rAddreの方の行の処理
                If arTest(i, 2) = arAddress(k, 4) Then '名前が一致するか
                    iii = iii + 1 'スタートが1なので先に1にしておく
                    arr(iii, 1) = arAddress(i, 2)    'クラス番号
                    arr(iii, 2) = arAddress(i, 3)     '出席番号
                    arr(iii, 3) = arAddress(i, 4)     '名前
                    arr(iii, 4) = arTest(k, 3)     '設備
                    arr(iii, 5) = arTest(k, 4)      '取扱
                    arr(iii, 6) = arTest(k, 5)      '法規
                End If
                If VBA.IsEmpty(arTest(i, 1)) Then Exit For
                If VBA.IsEmpty(arAddress(k, 1)) Then Exit For
            Next
   Next
   myTennki = arr
End Function
'myTennki(myGoukaku(rTest), myAddr(myGoukaku(rTest), rAddress))

実際に使う時は、以下のmyKansei関数を使います。引数は、2つの表の範囲を指定するだけです。今まで、作った関数を内部で使ってます。これをラッパー関数という。ラッピンですね。包装です。使いやすくするのが目的です。

内部で使っているmyTennkiやmyAddrはPrivate Functionにしてセルの入力時に使えないようにします。myKanseiだけ使えればいいので問題ありません。

'使いやすくする。ラッパー関数。2つのテーブルを引数にする
Function myKansei(rTest As Range, rAddress As Range)
    myKansei = myTennki(myGoukaku(rTest), myAddr(myGoukaku(rTest), rAddress))
End Function

2つの表のデータ作成用マクロは その1にあります。

エクセルマクロとは、ExcelオブジェクトとVBA仕様です。こうした関数は、ほぼVBAの知識だけでできます。

カテゴリー: 9 セルの中で使うユーザー定義関数の作成 <VBA> | コメントする