MW211 EXIT

devlog
ExcelVBA/入力補助のはずが無限ループ
2014年09月01日
シート記述するマクロで、以下のように記述すると
「Cells(2, 3)」に値を入力した場合、自動で「様」がついてくれる想定だ。
┌──────────────────────────────────────┐
│Private Sub Worksheet_Change(ByVal Target As Range)                         │
│    If Target.Row = 2 And Target.Column = 3 Then                            │
│        Target.Value = Target.Value & "様"                                  │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
でも実際に実行してみると、入力後「様様様…」という、大量の「様」がついてしまう。

これは、自分で自分の値を変えてその結果新たに自分を呼び出しているから
…つまり無限ループしてるって訳だ。

ということで、これを防ぐ方法。
┌──────────────────────────────────────┐
│Private Sub Worksheet_Change(ByVal Target As Range)                         │
│    If Target.Row = 2 And Target.Column = 3 Then                            │
│        Application.EnableEvents = False                                    │
│        Target.Value = Target.Value & "様"                                  │
│        Application.EnableEvents = True                                     │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
「Application.EnableEvents = False」で一旦自分が呼ばれないようにしてから
値を変えればいいってことだ。
もちろん、次のイベントのために、「True」で戻すことも忘れずに。
分類:ExcelVBA
ExcelVBA/MSSQLのトランザクション処理
2014年08月31日
下記のような流れとなる。
┌──────────────────────────────────────┐
│    Dim データベース As New ADODB.Connection                                │
│    Dim テーブル As New ADODB.Recordset                                     │
│    ────────────────────────────────────│
│    ' トランザクション開始                                                  │
│    データベース.connectionString = (省略)                                  │
│    データベース.Open                                                       │
│    On Error GoTo トランザクション中にエラー発生                            │
│    データベース.BeginTrans                                                 │
│    ────────────────────────────────────│
│    ' テーブル更新                                                          │
│    テーブル.ActiveConnection = データベース                                │
│    テーブル.Source = "テーブル名"                                          │
│    テーブル.CursorType = adOpenKeyset                                      │
│    テーブル.LockType = adLockOptimistic                                    │
│    テーブル.Open                                                           │
│    テーブル.Filter = "[キー]='" & キー                                     │
│    テーブル.Fields("更新項目").Value = 値                                  │
│    テーブル.Update                                                         │
│    テーブル.Close                                                          │
│    ────────────────────────────────────│
│    ' トランザクション完了                                                  │
│    データベース.CommitTrans                                                │
│    データベース.Close                                                      │
│    Set テーブル = Nothing                                                  │
│    Set データベース = Nothing                                              │
│    Exit Sub                                                                │
├──────────────────────────────────────┤
│トランザクション中にエラー発生:                                             │
│    ' ロールバック                                                          │
│    MsgBox "エラー発生!"                                                   │
│    データベース.RollbackTrans                                              │
│    データベース.Close                                                      │
│    Set テーブル = Nothing                                                  │
│    Set データベース = Nothing                                              │
└──────────────────────────────────────┘
自前でトランザクションのSQL文を発行するよりも
用意されているメソッドに従ってやった方がいいようだ。
(SQL文発行だとうまく行かなかった)
分類:ExcelVBA
SQL/二階層以上先のLEFT JOIN
2014年08月25日
あまりないかもしれないが、直上にはないけど、そのまた上にある列と
「LEFT JOIN」したい場合、普通に以下のように書いたらNGだ。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│   FROM 親                                                                  │
│       LEFT 子                                                              │
│         ON 子.列A = 親.列A                                                 │
│           LEFT 孫                                                          │
│             ON  孫.列B = 親.列B                  ←×                      │
│             AND 孫.列C = 子.列C;                                           │
└──────────────────────────────────────┘

こんな時は、一旦上の階層でテーブルを完結させて、列が揃った時点で
そこに「LEFT JOIN」すればよい。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│   FROM (SELECT *                                                           │
│             FROM 親                                                        │
│                 LEFT 子                                                    │
│                   ON 子.列A = 親.列A) AS 親たち                            │
│       LEFT 孫                                                              │
│         ON  孫.列B = 親たち.列B                  ←○                      │
│         AND 孫.列C = 親たち.列C;                                           │
└──────────────────────────────────────┘
VIEWとかを駆使すれば見やすくなる。

ちなみに結合するキーの関係を図示すると以下のような変化が起こったってことだ。
┌─────┐  ┌─────┐
│親  子  孫│→│親たち  孫│
│●=●  ○│  │●      ○│
│●  ○  ●│  │●===●│
│○  ●=●│  │●===●│
└─────┘  └─────┘
分類:SQL
ExcelVBA/ボタンのセル座標
2014年08月23日
押されたボタンのセルにおける座標を求める方法。

ボタン左上が属すセルのX座標とY座標は以下の通り。
x = ActiveSheet.Shapes(Application.Caller).TopLeftCell.Column
y = ActiveSheet.Shapes(Application.Caller).TopLeftCell.Row

ボタン右下が属すセルのX座標とY座標は以下の通り。
x = ActiveSheet.Shapes(Application.Caller).BottomRightCell.Column
y = ActiveSheet.Shapes(Application.Caller).BottomRightCell.Row

残念ながら、左下(BottomLeft)と右上(TopRight)はないようだ。
分類:ExcelVBA
ExcelVBA/複合論理演算子のわな
2014年08月20日
普通、以下のルールがある。
  ・「① AND ②」 …  ①が偽なら(偽なので)、②以降は判定しない
  ・「① OR ②」  …  ①が真なら(真なので)、②以降は判定しない
これを利用して、①で、②で判定する予定の変数の存在チェックなんかをして
うまいことやることができる。

しかし、ExcelVBAの「And」や「Or」では、
無条件に全ての条件式を(つまり②以降も)判定してしまうので、これが効かない。

VBA.netでは「AndAlso」や「OrElse」といったこれを実現する
論理演算子が追加されたが、ExcelVBAでは未実装なので
この事実を考慮してコーディングする必要があるようだ。
分類:ExcelVBA
Excel/条件付き書式
2014年08月19日
Excel2010の場合、メニューリボンより
  条件付き書式
  ↓
  セルの強調表示ルール
  ↓
  その他のルール
  ↓
  数式を使用して、書式設定するセルを決定。

例えば、セル「A1」にてセル「A2」と値が一致するか確認したい場合
「次の数式を満たす場合に値を書式設定」に以下の数式を入力。
  「=A1=A2」(=が不自然な形となるが気にしない)
「書式」ボタンで「セルの書式設定」を任意の値に設定(背景色を塗るなど)。

当該セルを書式コピー(書式のコピーのペイントブラシアイコン)で拡散することも可能。
分類:Excel
ExcelVBA/追加したボタンのイベント登録
2014年08月18日
「.OnAction」メソッドに関数名を文字列として登録する。
┌──────────────────────────────────────┐
│With ThisWorkbook.Worksheets("Sheet1")                                      │
│    With .Buttons.Add(Left, Top, Width, Height)                             │
│        .OnAction = "'clickAction(" & y * 100 + x & ")'"                    │
│    End With                                                                │
│End With                                                                    │
├──────────────────────────────────────┤
│Sub clickAction(z As Long)                                                  │
│    MsgBox z                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/セルに沿ってのボタン追加
2014年08月17日
以下のような感じ。(「x」と「y」は適宜座標の値を入れればよい)
┌──────────────────────────────────────┐
│With ThisWorkbook.Worksheets("Sheet1")                                      │
│    With .Buttons.Add(.Cells(y, x).Left, _                                  │
│                      .Cells(y, x).Top, _                                   │
│                      .Cells(y, x).Width, _                                 │
│                      .Cells(y, x).Height)                                  │
│        .Name = "button" & Format(y * 100 + x, "0000")                      │
│        .Font.Name = "MS ゴシック"                                        │
│        .Font.Size = 9                                                      │
│        .Text = "ボタン"                                                    │
│    End With                                                                │
│End With                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/オートフィルタを解除する
2014年08月16日
基本は以下の通り。
┌──────────────────────────────────────┐
│Worksheets.AutoFilterMode = False                                           │
└──────────────────────────────────────┘

「Worksheets」を部分を、以下のようにファイル内ループで全シートとかにすれば
一括解除できる。
┌──────────────────────────────────────┐
│Dim objSheet As Object                                                      │
│Dim sh As Worksheet                                                         │
│For Each sh In ThisWorkbook                                                 │
│    sh.AutoFilterMode = False                                               │
│Next sh                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
VBA/オブジェクトの始末
2014年08月15日
オブジェクトを作ったら、最後いや用無しになった段階で
「Nothing」を代入して解放してあげましょうね。
┌──────────────────────────────────────┐
│Set オブジェクト = Nothing                                                  │
└──────────────────────────────────────┘

以下のようにやってあげれば丁寧かも。
┌──────────────────────────────────────┐
│If オブジェクト IsNot Nothing Then Set オブジェクト = Nothing               │
├──────────────────────────────────────┤
│If Not オブジェクト Is Nothing Then Set オブジェクト = Nothing              │
└──────────────────────────────────────┘
いや、無駄か。う~ん、わからん。ただ単に無条件で代入してあげても問題ないかも。
分類:ExcelVBA
前へ 1 … 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 … 156 次へ