MW211 EXIT

devlog
ExcelVBA/ActiveXコントロールとメッセージボックス
2019年01月21日
ActiveXコントロールの表示内容を変更しても、
メッセージボックスが終了するまで画面に反映されない。。。
┌──────────────────────────────────────┐
│ActiveSheet.TextBox1.Value = Now                                            │
│' ここで一旦描画したい                                                      │
│MsgBox "処理は終わっているはずなのに"                                       │
└──────────────────────────────────────┘
「DoEvents」や「Application.ScreenUpdating = True」を使ってもダメ。

できないってことなのだろうか?(情報がみつからない)
ひとまず注意するしかないだろう
分類:ExcelVBA
ExcelVBA/配列中の重複を除去
2018年12月27日
連想配列を使う方法がよいらしい。
┌──────────────────────────────────────┐
│Private Function 配列重複除去(ByVal 配列 As Variant) As Variant             │
│    Dim i As Long, 連想配列 As Object                                       │
│    Set 連想配列 = CreateObject("Scripting.Dictionary")                     │
│    For i = 0 To UBound(配列)                                               │
│        If Not 連想配列.Exists(配列(i)) Then                                │
│            連想配列.Add 配列(i), ""                                        │
│        End If                                                              │
│    Next i                                                                  │
│    配列重複除去 = 連想配列.Keys                                            │
│End Function                                                                │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/クラス内のエラーを捕捉
2018年12月06日
クラス内でエラーが発生すると、外側(メソッド実行時点)でエラーで止まる。
これでは何がエラーなのかわからない。

しかし、以下の設定を変更すれば、クラス内のエラー箇所で止まるようになる。
┌──────────────────────────────────────┐
│「Microsoft Visual Basic for Applications」の                               │
│メニューバー「ツール」より「オプション」を選択                              │
│┌─────────────────────┐                              │
││オプション                                │                              │
│├─────────────────────┤                              │
││┌──┌──┌──┐──┐                │                              │
│││    │    │全般│    │                │                              │
││┌─────┘    └──────────┐│                              │
│││                                      ││                              │
│││  ┌エラートラップ─────────┐││                              │
│││  │○エラー発生時に中断            │←とにかくエラー箇所で止めたい場合│
│││  │●クラスモジュールで中断        │←クラス内エラー箇所で止めたい場合│
│││  │○エラー処理対象外のエラーで中断│←既定(On Errorで続行可能)        │
│└─────────────────────┘                              │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/キーブレイク
2018年12月05日
┌──────────────────────────────────────┐
│With 入力シート                                                             │
│    y入Max = .UsedRange.Rows(.UsedRange.Rows.Count).Row                     │
│    x出 = 1                                                                 │
│    ' 一件目                                                                │
│    y入 = 1                                                                 │
│    Do While y入 <= y入Max _                                                │
│         And .Cells(y入, Xキー).Value = ""                                  │
│        y入 = y入 + 1                                                       │
│    Loop                                                                    │
│    Do While y入 <= y入Max                                                  │
│        出力シート.Cells(y出, X見出).Value = .Cells(y入, X集合キー).Value   │
│        合計 = 0                                                            │
│        oldキー = .Cells(y入, X集合キー).Value                              │
│        Do                                                                  │
│            合計 = 合計 + .Cells(y入, X値).Value                            │
│            ' 次へ                                                          │
│            y入 = y入 + 1                                                   │
│            Do While y入 <= y入Max _                                        │
│                 And .Cells(y入, Xキー).Value = ""                          │
│                y入 = y入 + 1                                               │
│            Loop                                                            │
│        Loop While y入 <= y入Max _                                          │
│               And .Cells(y入, X集合キー).Value = oldキー                   │
│        出力シート.Cells(y出, X合計).Value = 合計                           │
│        x出 = x出 + 1                                                       │
│    Loop                                                                    │
│End With                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/画面分割の右下の左上を選択
2018年11月28日
┌─┬──┐
│  │    │
├─┼──┤
│  │★  │
│  │    │
└─┴──┘
上記における★を選択する方法。
┌──────────────────────────────────────┐
│シート.Select                                                               │
│シート.Cells(                                                               │
│    IIf(ActiveWindow.Split, ActiveWindow.SplitRow + 1, 1), _                │
│    IIf(ActiveWindow.Split, ActiveWindow.SplitColumn + 1, 1)                │
│).Select                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/印刷範囲を他シートへ転記
2018年11月27日
こんな感じ。
┌──────────────────────────────────────┐
│Dim 範囲 As Range                                                           │
│Dim y出 As Long, y入 As Long                                                │
│With Range(入力シート.PageSetup.PrintArea)                                  │
│    If .Item(.Count).Row = 1 Then                                           │
│        MsgBox "印刷範囲を拡大してください。", vbExclamation, "処理の中止"  │
│        Exit Sub                                                            │
│    End If                                                                  │
│    If .Item(1).Row = 1 Then                                                │
│        Set 範囲 = Range(.Item(2, 1), .Item(.Count))    ' ヘッダ行を除く    │
│    Else                                                                    │
│        Set 範囲 = Range(.Item(1), .Item(.Count))                           │
│    End If                                                                  │
│End With                                                                    │
│With 出力シート                                                             │
│    ' 転記するために行挿入(2行目以降に)                                     │
│    Application.CutCopyMode = False     ' コピー中のバッファをクリア        │
│    .Rows(2).Resize(範囲.Rows.Count).Insert _                               │
│                                        Shift:=xlDown, _                    │
│                                        CopyOrigin:=xlFormatFromRightOrBelow│
│    ' 転記                                                                  │
│    y出 = 2                                                                 │
│    For y入 = 範囲.Rows.Row To 範囲.Rows.Row + 範囲.Rows.Count - 1          │
│        .Cells(y出, x).Value = 入力シート.Cells(y入, x).Value               │
│        y出 = y出 + 1                                                       │
│    Next y入                                                                │
│End With                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/Range()とシート
2018年11月26日
┬──────────────────────────────────────┬
│Range()におけるシートの整合性                                               │
┴──────────────────────────────────────┴
┌──────────────────────────────────────┐
│シート◎.Range(シート①.Cells(y, x), シート②.Cells(y, x))                  │
└──────────────────────────────────────┘
  上記の場合、シート◎~②はすべて同一シートでなければならない
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  さもなくば、以下のエラーとなる
┌──────┬───────────────────────────────┐
│◎≠①の場合│実行時エラー'1004':                                           │
│◎≠②の場合│アプリケーション定義またはオブジェクト定義のエラーです。      │
├──────┼───────────────────────────────┤
│①≠②の場合│実行時エラー'1004':                                           │
│            │'Range'メソッドは失敗しました:'_Global'オブジェクト           │
├──────┼───────────────────────────────┤
│(後述)      │実行時エラー'1004':                                           │
│            │'Range'メソッドは失敗しました:'_Worksheet'オブジェクト        │
└──────┴───────────────────────────────┘
┬──────────────────────────────────────┬
│Range()におけるシート省略時の扱い                                           │
┴──────────────────────────────────────┴
┌──────────────────────────────────────┐
│Range(シート①.Cells(y, x), シート②.Cells(y, x))                           │
└──────────────────────────────────────┘
  基本的に、シート◎は省略可能でこの場合、シート①(=シート②)と同じになる
  →Cells()の場合は(シートを省略すると)ActiveSheet.Cells()となるので、
    これと同じようにActiveSheet.Range()となりそうに思われるが、この場合は
    独立したRangeオブジェクトとして、ActiveSheetには依存しない形となる
  ┌────────────────────────────────────┐
  │以下は一見同じように見えるが、シートB(=ActiveSheet)で実行すると        │
  │後者だけがエラーになる(①の親シートはシートAだからエラーとならない)     │
  │┌─┬──────────────────────────────┬─┐│
  ││①│            Range(シートA.Cells(1, 1), シートA.Cells(2, 2)) │○││
  │├─┼──────────────────────────────┼─┤│
  ││②│ActiveSheet.Range(シートA.Cells(1, 1), シートA.Cells(2, 2)) │×││
  │└─┴──────────────────────────────┴─┘│
  └────────────────────────────────────┘
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
┌──────────────────────────────────────┐
│シート◎.Range(ActiveSheet.Cells(y, x), ActiveSheet.Cells(y, x))            │
└──────────────────────────────────────┘
  シート①およびシート②を省略した場合は、(Cells()なので)ActiveSheet扱いとなる
  この場合、シート◎とActiveSheetが不一致だと前述の(◎≠①)エラーとなる
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  なお、親シートを調べたい場合には、以下で親シートのシート名が取得できる
┌──────────────────────────────────────┐
│Range(…).Parent.Name                                                       │
└──────────────────────────────────────┘
┬──────────────────────────────────────┬
│Range()の記述位置による挙動の違い                                           │
┴──────────────────────────────────────┴
  ソースコードをシートに記述するかモジュールに記述するかでも挙動が変わる
┌──────────────────────────────────────┐
│Range(シートA.Cells(1, 1), シートA.Cells(2, 2))                             │
└──────────────────────────────────────┘
  ○シートAを選択中に、モジュールに記述の上記処理を直接実行
  ○シートBを選択中に、モジュールに記述の上記処理を直接実行
  ○シートAを選択中に、モジュールに記述の上記処理をボタン押下で実行
  ○シートBを選択中に、モジュールに記述の上記処理をボタン押下で実行
  ○シートAを選択中に、シートAに記述の上記処理をボタン押下で実行
  ×シートBを選択中に、シートBに記述の上記処理をボタン押下で実行  →下記エラー
┌──────────────────────────────────────┐
│実行時エラー'1004':                                                         │
│'Range'メソッドは失敗しました:'_Worksheet'オブジェクト                      │
└──────────────────────────────────────┘
  このエラーは直前に「シートA.Cells(1, 1).Select」みたいに
  意図的にシートAをつかんでみても解消ができない
  (シートBに記述している時点でシートBの掌握下からは逃れられないようだ)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  解消するには以下のように「Range」の親シートを明示してあげればよい
┌──────────────────────────────────────┐
│シートA.Range(シートA.Cells(1, 1), シートA.Cells(2, 2))                     │
└──────────────────────────────────────┘
────────────────────────────────────────
分類:ExcelVBA
ExcelVBA/図が大きすぎます対策
2018年11月23日
大きな領域(例えばシートまるごと)をExcelVBAでコピーした後に、
ファイルを閉じると以下のエラーが発生する場合がある。
┌──────────────────────────────────────┐
│図が大きすぎます。入りきらない部分は切り捨てられます。                      │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│リソース不足のため、このタスクを完了することができません。                  │
│選択するデータを少なくするか、                                              │
│ほかのアプリケーションを終了して再度試してください。                        │
│元に戻さずに続けますか?                                                    │
└──────────────────────────────────────┘
クリップボードに大きなデータがあるために発生するエラーのようである。

よって、ファイルを閉じる前に、クリップボードをクリアすれば解決できるのだが
残念ながらExcelVBAでクリップボードを直接操作できない。

ということで代案。適当な領域をコピーした形にしてあげる。これでOK。
┌──────────────────────────────────────┐
│シート.Cells(1, 1).Copy                                                     │
└──────────────────────────────────────┘

ここまで来ると、コピー選択状態を以下のように解除してあげたくなる。
┌──────────────────────────────────────┐
│シート.Cells(1, 1).Copy                                                     │
│Application.CutCopyMode = False                                             │
└──────────────────────────────────────┘
しかしこれだと、効果がないようだ。

でも、1秒のdelayを挟んであげたらうまくいった。(裏で追いついてないってこと?)
┌──────────────────────────────────────┐
│シート.Cells(1, 1).Copy                                                     │
│Application.Wait Now + TimeValue("00:00:01")                                │
│Application.CutCopyMode = False                                             │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/xlLastCellとxlCellTypeLastCell
2018年11月22日
セルの末尾を表す以下の二つ、いずれも値は「11」で同じである
・「xlLastCell」
・「xlCellTypeLastCell」
分類:ExcelVBA
ExcelVBA/印刷範囲参照でエラーの克服方法
2018年11月21日
印刷範囲「シート.HPageBreaks」を参照した場合に
「実行時エラー'9' インデックスが有効範囲にありません」という
エラーが発生する場合がある。

主に印刷範囲が広い時に発生するようだ。

これはExcelのバグのようなものらしい。

解決策としては、参照前に
  (a) 当該セルの末尾(右下)に移動する
  (b) それを描画する
という二つの条件を満たせばいいとのこと

つまり、こんな感じにすればよい。
┌──────────────────────────────────────┐
│Application.ScreenUpdating = True                                     ' 描画│
│Application.GoTo シート.Cells(1, 1).SpecialCells(xlCellTypeLastCell)  ' 移動│
│' そして、シート.HPageBreaksを参照                                          │
└──────────────────────────────────────┘
分類:ExcelVBA
前へ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 … 27 次へ