MW211 EXIT

devlog
ExcelVBA/セル範囲と二次元配列
2018年06月29日
特定のセル範囲を配列に格納し、それを特定のセルを左上として貼り付ける処理。
┌──────────────────────────────────────┐
│Dim 配列 As Variant                                                         │
│配列 = セル範囲                                                             │
│セル.Resize(UBound(配列, 1), UBound(配列, 2)) = 配列                        │
└──────────────────────────────────────┘
UBound()の第二引数は次元数を指し、
この場合一次元目がY座標、二次元目がX座標となる。

あっ、だからCells()の引数が(一般的なものと反対の)Y→Xの順なんだろうか。
分類:ExcelVBA
ExcelVBA/ActiveXコントロールのイベント抑止
2018年06月28日
イベント自体の抑止はできないようなので(「Enabled=False」とかでも発生)、
イベント内でフラグ等で制御する他ないようだ。

まず、肝心のシートイベントにて、以下のように設定する。
┌──────────────────────────────────────┐
│Public mIsイベント抑止 As Boolean                                           │
├──────────────────────────────────────┤
│Private Sub ComboBox表示行数_Change()                                       │
│    If mIsイベント抑止 Then                                                 │
│        Exit Sub                                                            │
│    End If                                                                  │
│    Call 処理実行                                                           │
│End Sub                                                                     │
└──────────────────────────────────────┘
グローバル変数でも構わないが、せっかくなのでシートのメンバ変数で制御する。

初期化については、コンストラクタ的なものの記載を試みてもよいかもしれないが
ブックイベントがあるので「ThisWorkbook.cls」の初期化処理にて行う。
┌──────────────────────────────────────┐
│Private Sub Workbook_Open()                                                 │
│    シート.mIsイベント抑止 = False                                          │
│End Sub                                                                     │
└──────────────────────────────────────┘

後は、マクロ処理にて、事前にイベント抑止を宣言してから値を変更してあげればよい。
┌──────────────────────────────────────┐
│    With シート                                                             │
│        .mIsイベント抑止 = True                                             │
│        .ComboBox表示行数.ListIndex = インデックス                          │
│        Call 処理実行                                                       │
│        .mIsイベント抑止 = False                                            │
│    End With                                                                │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/列挙型と関数の名前の衝突
2018年06月27日
列挙型と関数では名前が衝突してしまう。
以下のようなエラーが出る。
┌────────────────┐
│コンパイルエラー:               │
│名前が適切ではありません: テスト│
└────────────────┘
以下のような場合にエラーとなるのだ。
┌──────────────────────────────────────┐
│Enum 列挙型                                                                 │
│    テスト                                                                  │
│End Enum                                                                    │
├──────────────────────────────────────┤
│Sub テスト()                                                                │
│    ' 実行するとエラーが出る                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
一方がPublicなら他方がPrivateでも衝突。
Private同士でも同じスコープに同居したら衝突となる。

但し、シートに関数を記述した場合には大丈夫。
→シート配下の関数となるので衝突が回避できる。

同じくフォームに関数を記述した場合でも大丈夫。
→フォーム配下の関数となるので衝突が回避できる。

もちろんクラス配下のメソッドの場合でも大丈夫。
→クラス(インスタンス)配下の関数となるので衝突が回避できる。

つまり、「.bas」にある関数との衝突に気をつければよい。
分類:ExcelVBA
ExcelVBA/見たままを取得
2018年06月26日
セルの書式設定で「yyyy"年"mm"月"dd"日"」に設定し、
「2018/6/18」を表示した場合、
値は「2018/6/18」だが表示は「2018年06月18日」となる。

ここでこのセルを「.Value」で取得すると値の「2018/6/18」となるが、
「2018年06月18日」として取得したい場合。

「.Text」を使えばよい。

  セル.Value  →  「2018/6/18」
  セル.Text   →  「2018年06月18日」
分類:ExcelVBA
ExcelVBA/エディタ表示がずれる
2018年06月25日
ActiveXコントロールのボタンのキャプションを変えると
VBAエディタ画面の表示がずれる(プロポーショナルっぽくなる)現象に遭遇。

原因はよくわからず、開発途中に何らかの理由で壊れたようなので
昔の正常だった状態に戻して(そこから差分を追加して)復旧した。

現象的には以下の通り。
・あるボタンをコピーして、文字サイズを変え、太字を標準に変えた
・そしてそのボタンのCaptionに値を入れて保存し、再度開くと現象が発生
  →どうやら起動時に内部イベントでエディタまでおかしくしてしまう模様
・文字サイズを元に戻し、太字に戻したら解消された
  →コピー元と差分があることにより、何らかの内部イベントが発生した?
・ボタンの表示が「MS ゴシック」から「MS 明朝」にしたら解消された
  →エディタ表示が「MS ゴシック」だからそれと関連してしまっていた?

ま、Excelが壊れてしまったら、復旧はあきらめて昔の状態からやり直すのが一番かも。

と思ったら、何かの拍子に再発してしまった。

そこで、メニューバー「ツール>オプション」を起動。
┌──────────────────────────────────────┐
│オプション                                                                  │
├──────────────────────────────────────┤
│┌─┌────────┐─┐─┐                                            │
││  │エディターの設定│  │  │                                            │
│┌─┘                └─────────────────────────┐│
││┌コードの表示色───────────┐  フォント名                    ││
│││┌────────────────┐│  ┌───────────┬─┐││
││││標準コード                      ││  │MS ゴシック(日本語) │▼│││
│││└────────────────┘│  └───────────┴─┘││
│││前景        背景        インジケーター  サイズ                        ││
│││┌──┬─┐┌──┬─┐┌──┬─┐│  ┌──┬─┐                  ││
││││自動│▼││自動│▼││自動│▼││  │10  │▼│                  ││
│││└──┴─┘└──┴─┘└──┴─┘│  └──┴─┘                  ││
││└──────────────────┘                                ││
└──────────────────────────────────────┘
フォント名を一旦「MS 明朝(日本語)」にしてExcelを保存して閉じる。
その後、起動して「MS ゴシック(日本語)」に戻してExcelを保存して閉じたら
なんとか復活できた。
分類:ExcelVBA
ExcelVBA/範囲を文字列に変換
2018年06月22日
┌─┬─┬─┬─┐
│  │  │  │  │
├─┌─┬─┬─┐
│  │a │b │c │  ┌───┐
├─├─┼─┼─┤  │a b c │
│  │d │e │f │→│d e f │
├─├─┼─┼─┤  │g h i │
│  │g │h │i │  └───┘
└─└─┴─┴─┘
セル範囲をテキストエディタに貼り付けて一つの文字列としたような変換のマクロ。
┌──────────────────────────────────────┐
│Const x始 As Long = 2, x終 As Long = 4                                      │
│Const y始 As Long = 2, y終 As Long = 4                                      │
├──────────────────────────────────────┤
│Sub 範囲を文字列に変換()                                                    │
│    Dim y As Long, 配列(y終 - y始) As String                                │
│    For y = y始 To y終                                                      │
│        配列(y - y始) = Join( _                                             │
│            WorksheetFunction.Index( _                                      │
│                Range(Cells(y, x始), Cells(y, x終)).Value, _                │
│                1, _                                                        │
│                0), _                                                       │
│            vbTab _                                                         │
│        )                                                                   │
│    Next y                                                                  │
│    MsgBox Join(配列, vbCrLf)                                               │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/コンボボックスの表示と値を別にする方法(続)
2018年06月21日
コンボボックスの表示と値を別にすると、Excelを閉じる時に
毎回当該ComboBoxのChangeイベントが発生してしまうので注意。

値  =BoundColumn=.Value
表示=TextColumn =.Text
の関係にあたるのだが、当該イベントにMsgBoxを仕込んで両者の値を確認してみると
.Text(表示)の値が.Value(値)の値に書き換わっている。

よって、.Textが値が変わったと見做して、Changeイベントが発生してしまうようだ。
(なんで.Textの値を変えるかは不明(事情があるのだろう、全体的にみればバグ?))

なので、コンボボックスの表示と値を別にするのはあまりよろしくないようだ。
分類:ExcelVBA
ExcelVBA/コンボボックスの表示と値を別にする方法
2018年06月20日
┌─┬────┐
│ 1│織田信長│
├─┼────┤
│ 2│豊臣秀吉│
├─┼────┤
│ 3│徳川家康│
└─┴────┘
上記のようなテーブルを用意し、コンボボックス(プルダウンメニュー)を生成するが
画面上は右列(名前)だけしか表示せず、処理的には左列(ID)を扱いたい場合の設定方法。

プロパティを以下のように設定する。
  ┌──────────┬───────┬───┬─────────────┐
  │ComboBoxのプロパティ│ListFillRange │A1:B3 │リストの実体              │
  │                    ├───────┼───┼─────────────┤
  │                    │ColumnCount   │2     │2列有効                   │
  │                    ├───────┼───┼─────────────┤
  │                    │BoundColumn   │1     │(.Valueで)1列目の値を取得 │
  │                    ├───────┼───┼─────────────┤
  │                    │TextColumn    │2     │選択時に2列目の値を表示   │
  │                    ├───────┼───┼─────────────┤
  │                    │ListWidth     │0 pt  │1列目を非表示に           │
  └──────────┴───────┴───┴─────────────┘
そして、処理にて以下のように参照する。
    値を「ComboBox.Value」で取得
    (「ComboBox.List(ComboBox.ListIndex, 0)」でも取得可)
分類:ExcelVBA
ExcelVBA/(Outlookで)メール送信
2018年06月18日
ExcelVBAでOutlookを使ってメールを送信するやり方。
┌──────────────────────────────────────┐
│' 事前に「ツール>参照設定」で                                              │
│' 「Microsoft Outlook 14.0 Object Library」を追加しておく                   │
├──────────────────────────────────────┤
│' メールの生成                                                              │
│    Dim objOutlook As Outlook.Application                                   │
│    Dim objメール As Outlook.mailItem                                       │
│    Set objOutlook = CreateObject("Outlook.Application")                    │
│    Set objメール = objOutlook.CreateItem(olMailItem)                       │
│    objメール.BodyFormat = 1           ' プレーンテキスト                   │
│    objメール.To = "xxxx@xxxx.co.jp"   ' 宛先TO                             │
│    objメール.CC = "xxxx@xxxx.co.jp"   ' 宛先CC                             │
│    objメール.BCC = "xxxx@xxxx.co.jp"  ' 宛先BCC                            │
│    objメール.Subject = "件名"                                              │
│    objメール.Body = "本文"                                                 │
├──────────────────────────────────────┤
│' ファイルの添付                                                            │
│    Dim obj添付 As Outlook.Attachments                                      │
│    Set obj添付 = objメール.Attachments                                     │
│    obj添付.Add "C:\添付ファイル.txt"                                       │
├──────────────────────────────────────┤
│' メールの送信                                                              │
│''''objメール.Save      ' 下書き保存                                        │
│    objメール.Display   ' メーラ表示(送信ボタンを押させる)                  │
│''''objメール.Send      ' 送信                                              │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/ScreenUpdatingの入れ子対策
2018年06月14日
┌─────────────────────────┐
│Application.ScreenUpdating = False                │
│┌───────────────────サブ関数┐│
││Application.ScreenUpdating = False            ││
││  :                                          ││
││Application.ScreenUpdating = True             ││
│└───────────────────────┘│
│Application.ScreenUpdating = True                 │
└─────────────────────────┘
Application.ScreenUpdatingが(意図せずして)入れ子になると
画面表示抑止の解除が早まってしまうので、入れ子内の方で工夫が必要
┌─────────────────────────┐
│Application.ScreenUpdating = False                │
│┌───────────────────サブ関数┐│
││Dim oldScreenUpdating As Boolean              ││
││oldScreenUpdating = Application.ScreenUpdating││
││If oldScreenUpdating Then                     ││
││    Application.ScreenUpdating = False        ││
││End If                                        ││
││  :                                          ││
││If oldScreenUpdating Then                     ││
││    Application.ScreenUpdating = True         ││
││End If                                        ││
│└───────────────────────┘│
│Application.ScreenUpdating = True                 │
└─────────────────────────┘
分類:ExcelVBA
前へ 1 … 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 … 27 次へ