MW211 EXIT

devlog
ExcelVBA/印刷が要求順で出力されない
2018年09月04日
いろいろ原因があるようだが、遭遇したものを一つ
・給紙が異なっていた
  「給紙A系(1)→給紙A系(2)→給紙B系(1)」の順に処理(印刷)したら
  「給紙A系(1)→給紙B系(1→給紙A系(2))」の順で印刷された
分類:ExcelVBA
ExcelVBA/文字色を透明にする
2018年09月02日
文字色を透明にするパラメータというのはない。
よって、背景色と同色にする対応となる。
以下のような感じ。
┌──────────────────────────────────────┐
│With Cells(1, 1)                                                            │
│    .Font.Color = .Interior.Color                                           │
│End With                                                                    │
└──────────────────────────────────────┘

複数範囲の場合は以下のような感じでもいけるのだが。
┌──────────────────────────────────────┐
│With Range(Cells(1, 1), Cells(2, 2))                                        │
│    .Font.Color = .Interior.Color                                           │
│End With                                                                    │
├──────────────────────────────────────┤
│With Union(Cells(1, 1), Cells(2, 2))                                        │
│    .Font.Color = .Interior.Color                                           │
│End With                                                                    │
└──────────────────────────────────────┘
範囲内の背景色に相違があると、黒(値0=RGB(0, 0, 0))になってしまうので
うまくいかない

そういった場合もあるので、For Eachで個別に対応していった方が安全なようだ。
┌──────────────────────────────────────┐
│Dim セル As Range                                                           │
│For Each セル In Union(Cells(1, 1), Cells(2, 2))                            │
│    セル.Font.Color = セル.Interior.Color                                   │
│Next セル                                                                   │
├──────────────────────────────────────┤
│Dim セル As Range                                                           │
│For Each セル In Range(Cells(1, 1), Cells(2, 2))                            │
│    セル.Font.Color = セル.Interior.Color                                   │
│Next セル                                                                   │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/Range型の右下
2018年08月31日
Range型のデータが矩形範囲の場合、そのまま行もしくは列を参照すると
左上基準で値が取得される
┌──────────────────────────────────────┐
│矩形範囲.Row    → 左上の上                                                 │
│矩形範囲.Column → 左上の左                                                 │
└──────────────────────────────────────┘

この場合以下のようにしてあげれば右下基準で値を取得できる。
┌──────────────────────────────────────┐
│矩形範囲.Cells(矩形範囲.Cells.Count).Row    → 右下の下                     │
│矩形範囲.Cells(矩形範囲.Cells.Count).Column → 右下の右                     │
└──────────────────────────────────────┘

つまり、以下のように取得できる。
┌──────────────────────────────────────┐
│Range("B3").Row                                          '→3               │
│Range("B3").Column                                       '→2               │
├──────────────────────────────────────┤
│Range("B3:C4").Row                                       '→3               │
│Range("B3:C4").Column                                    '→2               │
├──────────────────────────────────────┤
│Range("B3:E6").Cells(Range("B3:E6").Cells.Count).Row     '→6               │
│Range("B3:E6").Cells(Range("B3:E6").Cells.Count).Column  '→5               │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/A1形式の文字列をRange型に変換
2018年08月30日
A1形式の文字列(例えば「B3」)をRange型に変換する方法は実は簡単。
Range()にぶち込めばよいのだ。

すなわち「Range("B3")」でOK。

つまり、以下みたいな感じにできる。
┌──────────────────────────────────────┐
│Const 文字列 As String = "B3"                                               │
│Dim 範囲 As Range                                                           │
│範囲 = Range(文字列)                                                        │
│MsgBox 範囲.Column  '→2                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/Excel関数でPHPのimplode()代替
2018年08月28日
┌──────────────────────────────────────┐
│IMPLODE = Join(配列, 区切文字)                                              │
└──────────────────────────────────────┘
ExcelVBAにおけるPHPのimplode()と同等の関数は「Join()」なのだが
Excel関数には同等の関数が見当たらない。

ということで、VBA側の関数として実装してみる。
┌──────────────────────────────────────┐
│Public Function IMPLODE(ByVal 範囲 As Range, ByVal 区切文字 As String)      │
│    Dim 配列 As Variant, セル As Variant                                    │
│    配列 = Array()                                                          │
│    For Each セル In 範囲                                                   │
│        If セル.Value <> "" Then                                            │
│            ReDim Preserve 配列(UBound(配列) + 1)                           │
│            配列(UBound(配列)) = セル.Value                                 │
│        End If                                                              │
│    Next セル                                                               │
│    IMPLODE = Join(配列, 区切文字)                                          │
│End Function                                                                │
└──────────────────────────────────────┘
使用方法としては以下のようになる。
┌──────────────────────────────────────┐
│=IMPLODE(A1:B3,",")                                                         │
└──────────────────────────────────────┘
セル範囲を左上から右へそして下段へという範囲で空欄以外が抽出される。
分類:ExcelVBA
ExcelVBA/ActiveXコントロールのコピー
2018年08月27日
┌──────────────────────────────────────┐
│入力シート.Shapes("TextBox").Copy                                           │
│With 出力シート                                                             │
│    .Cells(1, 1).Select                                                     │
│    .Paste                                                                  │
│End With                                                                    │
└──────────────────────────────────────┘
上記のような感じでいけた。

但し、オブジェクト名は初期化されるようで「TextBox1」とかになる。
分類:ExcelVBA
ExcelVBA/別ファイルを開く(2)空のファイル
2018年08月26日
ちなみに、空のファイルを開く、というかアプリケーションを新規起動するには
以下のように「Shell()」(起動成功有無の戻り値あり)を実行してあげればよい。
┌─────┬────────────────────────────────┐
│Word      │Call Shell("winword.exe", vbNormalFocus)                        │
├─────┼────────────────────────────────┤
│Excel     │Call Shell("excel.exe", vbNormalFocus)                          │
├─────┼────────────────────────────────┤
│PowerPoint│Call Shell("powerpnt.exe", vbNormalFocus)                       │
├─────┼────────────────────────────────┤
│メモ帳    │Call Shell("notepad.exe", vbNormalFocus)                        │
└─────┴────────────────────────────────┘
いずれもパスが通っているという前提である。

これらを応用して、紐づいていないアプリで無理やりファイルを開くこともできる。
┌──────────────────────────────────────┐
│Call Shell("winword.exe " & Chr(34) & "C:\説明書.pdf" & Chr(34), _          │
│           vbNormalFocus)                                                   │
└──────────────────────────────────────┘
上記は、PDFファイルを無理やりメモ帳で開いた場合の例。
分類:ExcelVBA
ExcelVBA/別ファイルを開く(1)紐づくアプリで開く
2018年08月25日
ファイルがアプリケーションに紐づいているのであれば、
当該ファイルを以下のように、WSHから.Runしてあげればよい
┌──────────────────────────────────────┐
│Dim objWSH As Object                                                        │
│Set objWSH = CreateObject("Wscript.Shell")                                  │
│objWSH.Run Chr(34) & "C:\説明書.pdf" & Chr(34)                              │
└──────────────────────────────────────┘
パスはスペースが混じるといけないので、Chr(34)で囲っておいた方がよい。

ちなみにシェルから.ShellExecuteでも同様のことができる。
┌──────────────────────────────────────┐
│Dim objShell As Object                                                      │
│Set objShell = CreateObject("Shell.Application")                            │
│objShell.ShellExecute Chr(34) & "C:\説明書.pdf" & Chr(34)                   │
└──────────────────────────────────────┘

また、順番に複数のファイルを開くようにするには、第三引数に「True」を設定する。
これで、一つ目のファイルを閉じた時に二つ目のファイルが開くようにできる。
┌──────────────────────────────────────┐
│Dim objWSH As Object                                                        │
│Set objWSH = CreateObject("Wscript.Shell")                                  │
│objWSH.Run Chr(34) & "C:\説明書1.pdf" & Chr(34), 0, True                    │
│objWSH.Run Chr(34) & "C:\説明書2.pdf" & Chr(34)                             │
└──────────────────────────────────────┘
この指定がない場合には、最初の瞬間に両方のファイルがほぼ同時に開くことになる。
分類:ExcelVBA
ExcelVBA/テキストボックスの入力
2018年08月18日
【ActiveXコントロールのテキストボックスを入力不可にする方法】

  ■「.Enabled = Flase」にする
    →但し、文字色が淡くなる(濃くはできない)

  ■Textbox_Change()イベントで入力直後に元の値に戻す
    →但し、元の値がわかってなければならない
      (TextBox_GotFocus()イベントで取得しておくとか)
      また、イベントを再度起動してしまい無限ループに陥らないよう注意が必要

  □当該テキストボックスの保護ロックの状態にして(*1)
    シートを保護する(*2)
    但し、これは入力を不可とするものではなく
    デザインモード時にテキストボックスの位置やサイズを変更できなくするものの模様
    →つまり入力不可としては使えない

    *1:デザインモードで、右クリックメニュー「コントロールの書式設定」より
        「保護」タブの「■ロック」にチェックを入れる
    *2:シートの右クリックメニューから「シートの保護」を選ぶか
        リボンメニュー「ホーム」タブの「書式」から「シートの保護」を選ぶ

  □「.Locked = True」にする
    →これは前述の「■ロック」にチェックを入れたのと同等なので
      入力不可としては使えない

    なお、フォーム上のテキストボックスの場合は入力不可として使える模様
分類:ExcelVBA
ExcelVBA/ActiveXコントロール無限ループ
2018年08月17日
以下だと無限ループしてしまう。
┌──────────────────────────────────────┐
│Private Sub TextBox_Change()                                                │
│    Me.TextBox.Value = Rnd()                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘

以下は、Excelシート向けのイベント抑止なので効かない。
┌──────────────────────────────────────┐
│Private Sub TextBox_Change()                                                │
│    Application.EnableEvents = False                                        │
│    Me.TextBox.Value = Rnd()                                                │
│    Application.EnableEvents = True                                         │
│End Sub                                                                     │
└──────────────────────────────────────┘

回避方法としては地道にフラグ制御しかないようだ。
┌──────────────────────────────────────┐
│Private mIs無限ループ回避 As Boolean  ' 初期値はFalseになる                 │
│Private Sub TextBox_Change()                                                │
│    If mIs無限ループ回避 Then                                               │
│        mIs無限ループ回避 = False     ' 次回に向けて再初期化                │
│    Else                                                                    │
│        mIs無限ループ回避 = True      ' 代入処理より前に置くこと            │
│        Me.TextBox.Value = Rnd()                                            │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
なお、「mIs無限ループ回避 = True」の位置は、
「Me.TextBox.Value = Rnd()」の前になければ効かないので注意。
分類:ExcelVBA
前へ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 … 27 次へ