MW211 EXIT

devlog
ExcelVBA/入力チェックの後始末
2017年12月25日
入力チェックしたはいいが、警告ダイアログだけ出して、
不正な入力を野放しにしてはいけない(意味がない)。

クリアしちまえばいいのだろうが、
上書する前の元の値までなくなってしまうのはいただけない。

ということで、元の値に戻す方法。UNDOを使う。
┌──────────────────────────────────────┐
│Private Sub Worksheet_Change(ByVal Target As Range)                         │
│    If Target.Value <> "" Then                                              │
│        If Target.Value <> "御意" Then                                      │
│            MsgBox "入力エラー", vbCritical                                 │
│            Application.EnableEvents = False                                │
│            Application.Undo                                                │
│            Application.EnableEvents = True                                 │
│        End If                                                              │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
こんな感じ(「御意」と入力しないと元に戻される)。

まず、「Worksheet_Change()」は入力後のイベントのため
入力前の値を保持できていない。
そこで、UNDO「Application.Undo」。

但し、「Application.Undo」はイベントを発生させてしまうので、
「Application.EnableEvents = False」でイベント取得を無効にしてあげないと
永久ループとなってしまう。
→試しに、これを外して実行してみるとよくわかる(永久ループ)。
  ちなみに永久ループになったら焦らず「Ctrl+Pause」だ!
分類:ExcelVBA
ExcelVBA/Type(3)
2017年12月14日
Type(構造体)はJoin()できない
┌─┬────────────────────────────────────┐
│○│文字列 = Join(配列, ",")                                                │
├─┼────────────────────────────────────┤
│×│文字列 = Join(構造体, ",")                                              │
└─┴────────────────────────────────────┘
構造体を配列化できれば、Join()できそうなのだが、その術がなさそうだ。
よって、CSVデータは配列で扱った方がよさそうな感じである。
分類:ExcelVBA
ExcelVBA/Type(2)
2017年12月13日
Type(構造体)は配列化できる。
┌─────┬────────────────────────────────┐
│Typeの定義│Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │End Type                                                        │
├─────┼────────────────────────────────┤
│Typeの使用│Dim 配列構造体インスタンス(1 To 3) As 構造体                    │
│          │構造体インスタンス(1).列1 = 0;                                  │
│          │MsgBox 構造体インスタンス(1).列1                                │
└─────┴────────────────────────────────┘
もちろん動的配列もOK。

構造体の入れ子もできる。(サブ側を先に宣言しないとエラーとなるので注意)
┌─────┬────────────────────────────────┐
│Typeの定義│Type サブ構造体                                                 │
│          │    副列1        As Long                                        │
│          │    副列2        As String                                      │
│          │End Type                                                        │
│          │Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │    列3          As サブ構造体                                  │
│          │End Type                                                        │
└─────┴────────────────────────────────┘
さらには動的配列にもできる。
┌─────┬────────────────────────────────┐
│Typeの定義│Type サブ構造体                                                 │
│          │    副列1        As Long                                        │
│          │    副列2        As String                                      │
│          │End Type                                                        │
│          │Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │    列3()        As サブ構造体                                  │
│          │End Type                                                        │
└─────┴────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/クリップボード
2017年12月12日
クリップボードの制御には、参照設定「Microsoft Forms 2.0 Object Library」が必要。

「,」付きの数値をコピーした場合に、
クリップボード上では「,」を除外する方法を模索中。
┌──────────────────────────────────────┐
│Option Explicit                                                             │
│Private Sub Worksheet_SelectionChange(ByVal Target As Range)                │
│    Dim myData As New DataObject                                            │
│    On Error Resume Next                                                    │
│    myData.GetFromClipboard                                                 │
│    myData.SetText Replace(myData.GetText, ",", "")                         │
│    myData.PutInClipboard                                                   │
│End Sub                                                                     │
└──────────────────────────────────────┘
こんな感じか?さてどのイベントで拾おうか。。。

ちなみにショートカットキー「ctrl+c」を登録して
以下の関数を呼び出すというのもありかも。
┌──────────────────────────────────────┐
│Option Explicit                                                             │
│Public Sub ctrlc()                                                          │
│    Dim clipBoard As New DataObject                                         │
│    On Error Resume Next                                                    │
│    clipBoard.SetText Replace(ActiveCell.Value, ",", "")                    │
│    clipBoard.PutInClipboard                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/正規表現のモンテカルロ法による検証
2017年12月01日
┌──────────────────────────────────────┐
│Option Explicit                                                             │
├──────────────────────────────────────┤
│Public Sub 正規表現のモンテカルロ法による検証()                             │
│    Dim REG As Object: Set REG = CreateObject("VBScript.RegExp")            │
│    Dim i As Long, 検証文字 As String                                       │
│    Dim y1 As Long: y1 = 1                                                  │
│    Dim y2 As Long: y2 = 1                                                  │
│    Cells.ClearContents                                                     │
│    Cells(1, 1).Value = "【一致】"                                          │
│    Cells(1, 2).Value = "【不一致】"                                        │
│    REG.Pattern = "^[A-Z]+$"    ' ここに検証したい正規表現を指定            │
│    Randomize                                                               │
│    For i = 1 To 60000                                                      │
│        検証文字 = ランダム文字生成()                                       │
│        If REG.test(検証文字) Then                                          │
│            y1 = y1 + 1                                                     │
│            Cells(y1, 1).Value = 検証文字                                   │
│        Else                                                                │
│            y2 = y2 + 1                                                     │
│            Cells(y2, 2).Value = 検証文字                                   │
│        End If                                                              │
│    Next i                                                                  │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Private Function ランダム文字生成() As String                               │
│    Dim 結果 As String: 結果 = ""                                           │
│    Dim i As Long, iMax As Long, dw(0 To 2) As String                       │
│    iMax = Int(Rnd * 8) + 4                                                 │
│    For i = 1 To iMax                                                       │
│        dw(0) = Int(Rnd * 10)               ' 数字(0~9)                    │
│        dw(1) = Chr(Int(Rnd * 26) + 65)     ' 英大文字(A~Z)                │
│        dw(2) = Chr(Int(Rnd * 26) + 97)     ' 英小文字(a~z)                │
│        結果 = 結果 & dw(Rnd * 2)                                           │
│    Next i                                                                  │
│    ランダム文字生成 = 結果                                                 │
│End Function                                                                │
└──────────────────────────────────────┘
数値版の場合は以下の通り。
┌──────────────────────────────────────┐
│Option Explicit                                                             │
├──────────────────────────────────────┤
│Public Sub 正規表現のモンテカルロ法による検証数値版()                       │
│    Dim REG As Object: Set REG = CreateObject("VBScript.RegExp")            │
│    Dim i As Long, 検証数値 As Long                                         │
│    Dim y1 As Long: y1 = 1                                                  │
│    Dim y2 As Long: y2 = 1                                                  │
│    Cells.ClearContents                                                     │
│    Cells(1, 1).Value = "【一致】"                                          │
│    Cells(1, 2).Value = "【不一致】"                                        │
│    REG.Pattern = "^(?:0|[1-9]|1[0-2])$"    ' ここに検証したい正規表現を指定│
│    Randomize                                                               │
│    For i = 1 To 60000                                                      │
│        検証数値 = Int(Rnd * 65536)                                         │
│        If REG.test(検証数値) Then                                          │
│            y1 = y1 + 1                                                     │
│            Cells(y1, 1).Value = 検証数値                                   │
│        Else                                                                │
│            y2 = y2 + 1                                                     │
│            Cells(y2, 2).Value = 検証数値                                   │
│        End If                                                              │
│    Next i                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/乱数
2017年11月30日
たとえばこんな感じ。
┌──────────────────────────────────────┐
│Public Sub ランダム文字生成()                                               │
│    Dim result As String: result = ""                                       │
│    Dim i As Long, dw(0 To 2) As String                                     │
│    Randomize                                                               │
│    For i = 1 To 8                                                          │
│        dw(0) = Int(Rnd * 10)               ' 数字(0~9)                    │
│        dw(1) = Chr(Int(Rnd * 26) + 65)     ' 英大文字(A~Z)                │
│        dw(2) = Chr(Int(Rnd * 26) + 97)     ' 英小文字(a~z)                │
│        result = result & dw(Rnd * 2)                                       │
│    Next i                                                                  │
│    MsgBox result                                                           │
│End Sub                                                                     │
└──────────────────────────────────────┘
要点としては以下の通りである。
┌───────┬──────────────────────────────┐
│Randomize     │乱数をシャッフル                                            │
├───────┼──────────────────────────────┤
│Rnd           │0以上1未満                                                  │
├───────┼──────────────────────────────┤
│Int(Rnd * 10) │0~9                                                        │
└───────┴──────────────────────────────┘
分類:ExcelVBA
ExcelVBA/存在チェックいろいろ
2017年11月22日
存在チェックのやり方を遅い順に列挙してみた。
┌──────────────────────────────────────┐
│Set 検索 = 範囲.Find( _                                                     │
│    What:=セル.Value, _                                                     │
│    After:=セル, _                                                          │
│    LookIn:=xlValues, _                                                     │
│    Lookat:=xlWhole, _                                                      │
│    SearchOrder:=xlByRows, _                                                │
│    SearchDirection:=xlNext, _                                              │
│    MatchCase:=True, _                                                      │
│    MatchByte:=True _                                                       │
│)                                                                           │
│If 検索.Address <> セル.Address Then                                        │
│    ' 重複あり                                                              │
│Else                                                                        │
│    ' 重複なし                                                              │
│End If                                                                      │
├──────────────────────────────────────┤
│If WorksheetFunction.CountIf(範囲, セル.Value) > 0 Then                     │
│    ' 重複あり                                                              │
│Else                                                                        │
│    ' 重複なし                                                              │
│End If                                                                      │
├──────────────────────────────────────┤
│On Error Resume Next                                                        │
│Call WorksheetFunction.VLookup(セル.Value, 範囲, 1, False)                  │
│If Err.Number = 0 Then                                                      │
│    ' 重複あり                                                              │
│Else                                                                        │
│    ' 重複なし                                                              │
│End If                                                                      │
│On Error GoTo 0                                                             │
├──────────────────────────────────────┤
│On Error Resume Next                                                        │
│Call WorksheetFunction.Match(範囲, セル.Value, 0)                           │
│If Err.Number = 0 Then                                                      │
│    ' 重複あり                                                              │
│Else                                                                        │
│    ' 重複なし                                                              │
│End If                                                                      │
│On Error GoTo 0                                                             │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/Type
2017年11月15日
Type(構造体)のいろいろ。こんな感じということで。
┌─────┬────────────────────────────────┐
│Typeの定義│Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │End Type                                                        │
├─────┼────────────────────────────────┤
│Typeの使用│Dim 構造体インスタンス As 構造体                                │
│          │構造体インスタンス.列1 = 0;                                     │
│          │MsgBox 構造体インスタンス.列1                                   │
│          │Call 関数(構造体インスタンス)                                   │
│          │────────────────────────────────│
│          │Sub 関数(ByVal 引数インスタンス As 構造体)                      │
│          │    MsgBox 構造体インスタンス.列1                               │
│          │End Sub                                                         │
└─────┴────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/.NumberFormatの違い
2017年11月14日
「.NumberFormatLocal」の方が、通常の画面入力(「セルの書式設定」)に近い。
  ┌──────────────────┬──────────────────┐
  │         .NumberFormatLocal         │           .NumberFormat            │
  ├──────────────────┼──────────────────┤
  │標準書式(書式なし)の指定            │標準書式(書式なし)の指定            │
  │.NumberFormatLocal = "G/標準"       │.NumberFormat = "General"           │
  ├──────────────────┼──────────────────┤
  │文字色の指定                        │文字色の指定                        │
  │.NumberFormatLocal = "0;[赤]-0"     │.NumberFormat = "0;[Red]-0"         │
  ├──────────────────┼──────────────────┤
  │円マークのの指定                    │文字色の指定                        │
  │.NumberFormatLocal = "\0"           │.NumberFormat = """\""0"            │
  └──────────────────┴──────────────────┘
「.NumberFormatLocal」を使った方がいいのでは?
分類:ExcelVBA
ExcelVBA/IIf()で除数ゼロエラー回避はできない
2017年10月21日
除数ゼロエラー回避のため、以下のようなIf文を用いたとする。
┌──────────────────────────────────────┐
│If 分母 = 0 Then                                                            │
│    比率 = 999                                                              │
│Else                                                                        │
│    比率 = 分子 * 100 / 分母                                                │
│EndIf                                                                       │
└──────────────────────────────────────┘
あ、これ三項式でいけるじゃんと思い、「IIf()」で実装を試みてみる。
┌──────────────────────────────────────┐
│比率 = IIf(分母 = 0, 999, 分子 * 100 / 分母)                                │
└──────────────────────────────────────┘
でも、これだと除数ゼロエラーが発生してしまう。
「IIf()」は偽の式も評価されてしまうのである。
ということで、If文を使うしかあるまい。
(VisualBasicだと「If()」ってのが新登場したとかしないとか)
分類:ExcelVBA
前へ 1 … 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 … 27 次へ