MW211 EXIT

devlog
ExcelVBA/引数の参照渡しと値渡し
2014年09月30日
なんと、VBAでは「参照渡し」がデフォルトなのだ。要注意。

【参照渡し(アドレス渡し)】(既定)
┌──────────────────────────────────────┐
│Sub 関数(引数)                                                              │
│    処理                                                                    │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Sub 関数(ByRef 引数)                                                        │
│    処理                                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘
→指定した引数が、関数内の処理により影響を受ける。(速度が速い)

【値渡し】
┌──────────────────────────────────────┐
│Sub 関数(ByVal 引数)                                                        │
│    処理                                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘
→指定した引数が、関数内の処理により影響を受けない。

ちなみに、以下のように実験してみたところ、結果は「参照渡し」が出力された。
つまり、既定(指定なし)は、参照渡しということが確認できる。
┌──────────────────────────────────────┐
│Sub 実験()                                                                  │
│    Dim 変数 As String                                                      │
│    変数 = "値渡し"                                                         │
│    Call サブ関数(変数)                                                     │
│    MsgBox 変数                                                             │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Sub サブ関数(変数 As String)                                                │
│    変数 = "参照渡し"                                                       │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/With句で自身を表すメタ文字はない?
2014年09月29日
┌──────────────────────────────────────┐
│Me.StartUpPosition = 2                                                      │
│Unload Me                                                                   │
└──────────────────────────────────────┘
例えば上記のような場合、下位のようにWith句でまとめたとする。
┌──────────────────────────────────────┐
│With Me                                                                     │
│    .StartUpPosition = 2                                                    │
│    Unload Me                                                               │
│End With                                                                    │
└──────────────────────────────────────┘
ただこれだと、まだ「Unload Me」の「Me」とWith句の「Me」が
かぶっているのでもう少し整理したい気がする(このままでも動くが)。
で、パス指定における「Unload .」的な感じにできないか?と思うのだが
そのようなものはないようだ。
ま、無理やりWith句にまとめんなという話だわな。
分類:ExcelVBA
ExcelVBA/フォームの表示位置指定
2014年09月28日
「UserForm_Initialize()」にて、フォームの初期表示位置を以下のように設定する。
┌───────────┬──────────────────────────┐
│Me.StartUpPosition = 0│任意                                                │
│       Me.Top  = Y座標│                                                    │
│       Me.Left = X座標│                                                    │
├───────────┼──────────────────────────┤
│Me.StartUpPosition = 1│フォームが属する項目の中央                          │
├───────────┼──────────────────────────┤
│Me.StartUpPosition = 2│画面全体の中央                                      │
├───────────┼──────────────────────────┤
│Me.StartUpPosition = 3│画面全体の左上                                      │
└───────────┴──────────────────────────┘

任意指定の場合、座標は以下のような感じで指定する。
┌──┬───────────────────────────────────┐
│縦上│Me.Top = Application.Top                                              │
│縦中│Me.Top = Application.Top + ((Application.Height - Me.Height) / 2)     │
│縦下│Me.Top = Application.Top - Application.Height - Me.Height             │
├──┼───────────────────────────────────┤
│横左│Me.Left = Application.Left                                            │
│横中│Me.Left = Application.Left + ((Application.Width - Me.Width) / 2)     │
│横右│Me.Left = Application.Left + Application.Width - Me.Width             │
└──┴───────────────────────────────────┘
もちろんダイレクトに座標を数値で代入しても可。
分類:ExcelVBA
ExcelVBA/シートの表示位置指定
2014年09月27日
左上に表示したいセルを以下のように指定する。
┌──────────────────────────────────────┐
│ActiveWindow.ScrollRow = セルのY座標                                        │
│ActiveWindow.ScrollColumn = セルのX座標                                     │
└──────────────────────────────────────┘

例えば、セルB2を左上に表示する場合には、以下のようになる。
┌──────────────────────────────────────┐
│ActiveWindow.ScrollRow = 2                                                  │
│ActiveWindow.ScrollColumn = 3                                               │
└──────────────────────────────────────┘
分類:ExcelVBA
MSSQL/IDENTIFY(自動連番)
2014年09月26日
【IDENTIFY(自動連番)の現在値を確認する方法】
┌──────────────────────────────────────┐
│DBCC CHECKIDENT (表名, NORESEED);                                           │
└──────────────────────────────────────┘
  次回採番されるのは「現在値+1」となる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【IDENTIFY(自動連番)の現在値を列の最大値以上にする】
┌──────────────────────────────────────┐
│DBCC CHECKIDENT (表名);                                                     │
├──────────────────────────────────────┤
│DBCC CHECKIDENT (表名, RESEED);                                             │
└──────────────────────────────────────┘
  既に現在値が最大値以上の場合は変化なし。
  次回採番されるのは「現在値(最大値)+1」となる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【IDENTIFY(自動連番)の現在値を任意の値にする】
┌──────────────────────────────────────┐
│DBCC CHECKIDENT (表名, RESEED, 値);                                         │
└──────────────────────────────────────┘
  最大値以下にも設定できるが、次回採番(INSERT)時に重複エラーとなる恐れあり。
  「Microsoft SQL Server Management Studio」で実行した場合、
  変更前の現在値を結果出力してから、変更が行われるので
  一見効果がないように錯覚しがち(もう一回実行すれば確認できる)。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【IDENTIFY(自動連番)の現在値を初期値にする】
┌──────────────────────────────────────┐
│DBCC CHECKIDENT (表名, RESEED, 0);                                          │
└──────────────────────────────────────┘
  次回採番されるのは「1」からとなる。
  「TRUNCATE TABLE」命令時にもこれと同様になる
分類:MSSQL
ExcelVBA/RangeとCells
2014年09月25日
Range()とCells()の組み合わせで、シート指定が絡んできた場合についてまとめた

【実験内容】
  「Sheet1」にてマクロを実行し「Sheet2」に値を出力できるか試してみる
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
○Range()もCells()も同じシートを指している場合                →「Sheet2」に出力
┌──────────────────────────────────────┐
│With ThisWorkbook.Worksheets("Sheet2")                                      │
│    .Range(.Cells(1, 1), .Cells(2, 2)).Value = "値"                         │
│End With                                                                    │
└──────────────────────────────────────┘
アクティブシートが「Sheet2」だったら、オーソドックスな
「Range(Cells(1, 1), Cells(2, 2)).Value = "値"」と同じことになる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
△Range()もCells()もシートの指定をしない場合                  →「Sheet1」に出力
┌──────────────────────────────────────┐
│With ThisWorkbook.Worksheets("Sheet2")                                      │
│    Range(Cells(1, 1), Cells(2, 2)).Value = "値"                            │
│End With                                                                    │
└──────────────────────────────────────┘
アクティブシートが「Sheet1」だから、上記同様「Sheet1」に出力される。
With句は意味をなさないことになる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
○Cells()だけでもちゃんとシートを指定してる場合               →「Sheet2」に出力
┌──────────────────────────────────────┐
│With ThisWorkbook.Worksheets("Sheet2")                                      │
│    Range(.Cells(1, 1), .Cells(2, 2)).Value = "値"                          │
│End With                                                                    │
└──────────────────────────────────────┘
Range()は「Sheet1」(アクティブシート)傘下なのに、
問題なく「Sheet2」に出力される。
よって、Range()は関数的な扱いとしてシートの指定は省略できるといえそう。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
×Range()とCells()でシート指定に相違がある場合                          →エラー
┌──────────────────────────────────────┐
│With ThisWorkbook.Worksheets("Sheet2")                                      │
│    .Range(Cells(1, 1), Cells(2, 2)).Value = "値"                           │
│End With                                                                    │
└──────────────────────────────────────┘
Range()は「Sheet2」を指定しているのに、
Cells()は指定なしでアクティブシート(「Sheet1」)指定となるので
両者に相違が発生しエラーとなる。
ちなみに「Sheet2」をアクティブシートにしておくと
両者は一致するので「Sheet2」に出力される。

相違があるという点では一つ前のパターンと同じなのだがこちらはダメなのだ。
┌──────────────┬───┬───┐
│                            │Sheet1│Sheet2│
├──────────────┼───┼───┤
│Worksheets("Sheet1").Range()│      │      │
│Worksheets("Sheet2").Cells()│  ×  │  ○  │
└──────────────┴───┴───┘
分類:ExcelVBA
MSSQL/NULLから空文字の場合
2014年09月24日
NULLの場合、既定値を出力には以下のような感じとなる。
┌──────────────────────────────────────┐
│ISNULL(列, 既定値)                                                          │
└──────────────────────────────────────┘

これがNULLもしくは空文字としたい場合は、以下でOK。
┌──────────────────────────────────────┐
│ISNULL(NULLIF(列, ''), 既定値)                                              │
└──────────────────────────────────────┘
「NULLIF()」は値を比較して同一ならNULLを返す関数だ。
分類:MSSQL
ExcelVBA/ソースコード出力
2014年09月23日
ExcelVBAのソースコードを一括してエクスポートしたい場合には
以下のようなマクロを使えばよい
#個人用マクロブック(PERSONAL.XLS)に登録しておけばいつでも使える
┌──────────────────────────────────────┐
│Sub ExcelVBAソースコード出力()                                              │
│    Dim VBC As Variant                                                      │
│    For Each VBC In ActiveWorkbook.VBProject.VBComponents                   │
│        If VBC.CodeModule.CountOfLines > 0 Then                             │
│            Select Case VBC.Type                                            │
│                Case 1      ' 標準モジュール                                │
│                    VBC.Export ActiveWorkbook.Path & "\" & VBC.Name & ".bas"│
│                Case 2      ' クラスモジュール                              │
│                    VBC.Export ActiveWorkbook.Path & "\" & VBC.Name & ".cls"│
│                Case 3      ' フォーム                                      │
│                    VBC.Export ActiveWorkbook.Path & "\" & VBC.Name & ".frm"│
│                Case 100    ' ドキュメント(ブック・シート)                  │
│                    VBC.Export ActiveWorkbook.Path & "\" & VBC.Name & ".cls"│
│            End Select                                                      │
│        End If                                                              │
│    Next VBC                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘

ちなみに「.CodeModule.CountOfLines > 0」で、
ソースコードのあるファイルに限定して出力している。
これがないとマクロのない通常のシートもファイルとして出力されてしまう。

ちなみに、以下のようにすると処理があるファイルのみ(宣言のみのファイルを除く)に
限定することもできる。
「.CodeModule.CountOfDeclarationLines <> .CodeModule.CountOfLines」
「.CountOfLines」がソース全行数、「.CountOfDeclarationLines」が宣言行数を
それぞれ取得できるからだ。(両者が一致するということは宣言のみということになる)
分類:ExcelVBA
設計/追加・変更・削除の作業順
2014年09月22日
同一明細にて、「追加(INSERT)・変更(UPDATE)・削除(DELETE)」を
同時に指定できる場合、漫然と「追加→変更→削除」の順で処理してもよいが、
「変更→削除→追加」の方がいいのではいだろうか。
※ここでは、追加(INSERT)は新規ID(自動的に末番)を付番し、
  変更(UPDATE)・削除(DELETE)は既存IDに対して更新するものとする

つまり、マトリックス表的には以下の関係となる。
┌──┬──┬──┬──┐
│ → │追加│変更│削除│
├──┼──┼──┼──┤
│追加│ \ │ × │ × │
├──┼──┼──┼──┤
│変更│ ○ │ \ │ ○ │
├──┼──┼──┼──┤
│削除│ ○ │ × │ \ │
└──┴──┴──┴──┘
  ×削除→変更
    先に削除をしてしまうと同一IDに変更指示があった場合、
    変更処理にて該当なしエラーとなってしまう。
    結果的に削除されるのであれば、おとなしく変更を先にしてしまえばよい
  ×追加→変更・削除
    追加にて新規IDが付番されるのだが、変更・削除にてたまたまそのIDを
    指定していると、該当なしエラーとなるべきところ通ってしまう

ということで、「変更→削除→追加」の順がベスト。

もちろん、場合によりけりだけど。
分類:設計
ExcelVBA/マクロメニューに表示させない方法
2014年09月21日
関数をPrivate関数とする。
┌──────────────────────────────────────┐
│Private Sub 関数()                                                          │
│  …                                                                        │
│End Sub                                                                     │
└──────────────────────────────────────┘

他もモジュールでも使っているのでPublic関数じゃなきゃダメな場合には
そのモジュール自体をPrivateモジュールにしてしまう。
┌──────────────────────────────────────┐
│Option Private Module                                                       │
│Public Sub 関数()                                                           │
│  …                                                                        │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
前へ 1 2 3 次へ