MW211 EXIT

devlog
ExcelVBA/ActiveXが存在するか?
2019年09月11日
例えば、特定のラベルの値(キャプション)を取得する場合に
そのラベルが存在しない場合にはエラーとなる。

これを回避するには事前に存在チェックする必要がある。

しかし、その存在チェックは簡単にはできない。

以下のようにActiveXコントロールを検索し
該当する名称のものがあるかいないかで判断する形となる。
┌──────────────────────────────────────┐
│Dim 図形 As Shape                                                           │
│With シート                                                                 │
│    For Each 図形 In .Shapes                                                │
│        If 図形.Type = msoOLEControlObject Then                             │
│            MsgBox 図形.Name                                                │
│        End If                                                              │
│    Next 図形                                                               │
│End With                                                                    │
└──────────────────────────────────────┘
自前のサブ関数を作るのがよいだろう。
分類:ExcelVBA
ExcelVBA/引数を配列にする方法
2019年09月10日
┌──────────────────────────────────────┐
│Call 関数(Array("a", "b", "c"))                                             │
├──────────────────────────────────────┤
│Public Sub 関数(ByVal 引数 As Variant)                                      │
│    Dim 値 As Variant                                                       │
│    For Each 値 In 引数                                                     │
│        MsgBox 値                                                           │
│    Next 値                                                                 │
│End Sub                                                                     │
└──────────────────────────────────────┘
基本的に配列で渡してVariant型で受ければよい。

ParamArrayオプションを付けると引数自体を配列(可変)にすることもできる。
┌──────────────────────────────────────┐
│Call 関数("a", "b", "c")                                                    │
├──────────────────────────────────────┤
│Public Sub 関数(ParamArray 引数() As Variant)                               │
│    Dim 値 As Variant                                                       │
│    For Each 値 In 引数                                                     │
│        MsgBox 値                                                           │
│    Next 値                                                                 │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/ExcelのRange型からCells型への変換
2019年09月07日
ということでExcelVBA版を作った。いい感じ。
┌──────────────────────────────────────┐
│Public Sub セル範囲変換Range→Cells()                                       │
│    Dim theCell As Range                                                    │
│    Dim theMatches As Object, theMatch  As Object                           │
│    Dim REG As Object                                                       │
│    Set REG = CreateObject("VBScript.RegExp")                               │
│    REG.Global = False                                                      │
│    For Each theCell In Selection                                           │
│        ' Range("A1")形式を置換                                             │
│        REG.Pattern = "Range\(""([A-Z]+)(\d+)""\)"                          │
│        Do While REG.Test(theCell.Value)                                    │
│            Set theMatches = REG.Execute(theCell.Value)                     │
│            For Each theMatch In theMatches                                 │
│                theCell.Value = REG.Replace( _                              │
│                    theCell.Value, _                                        │
│               "Cells($2, " & Columns(theMatch.SubMatches(0)).Column & ")" _│
│                )                                                           │
│            Next theMatch                                                   │
│        Loop                                                                │
│        ' Range("A1:B2")形式を置換                                          │
│        REG.Pattern = "Range\(""([A-Z]+)(\d+):([A-Z]+)(\d+)""\)"            │
│        Do While REG.Test(theCell.Value)                                    │
│            Set theMatches = REG.Execute(theCell.Value)                     │
│            For Each theMatch In theMatches                                 │
│                theCell.Value = REG.Replace( _                              │
│                    theCell.Value, _                                        │
│                    "Range(" _                                              │
│      & "Cells($2, " & Columns(theMatch.SubMatches(0)).Column & ")" & ", " _│
│      & "Cells($4, " & Columns(theMatch.SubMatches(2)).Column & ")" & ")" _ │
│                )                                                           │
│            Next theMatch                                                   │
│        Loop                                                                │
│    Next theCell                                                            │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
秀丸/ExcelのRange型からCells型への変換
2019年09月06日
┌──┬───────────────────────────────────┐
│検索│Range\("([A-Z]+)(\d+):([A-Z]+)(\d+)"\)                                │
├──┼───────────────────────────────────┤
│置換│Range(Cells(\2, \1), Cells(\4, \3))                                   │
└──┴───────────────────────────────────┘
「Range("A2:C4")」→「Range(Cells(2, A), Cells(4, C))」

ここまではできた

ABC…を123…に変換するところで行き詰ったので、これ以上はVBAでやることにした。
「変換関数(\1)」みたいなことができりゃいいんだけどね
分類:秀丸エディタ
ExcelVBA/任意の文字列たちを結合するが空文字は除く
2019年08月29日
例えば任意の複数の文字列を区切り文字で結合したい場合に
以下のようにすればよい。
┌──────────────────────────────────────┐
│CSV結果 = Join(Array(文字列1, 文字列2, 文字列3), ",")                       │
└──────────────────────────────────────┘
非常にお手軽なのだが難点があって、文字列が空文字の場合にも
「,,」みたいに結合されてしまう。(CSV的にはOKかもしれないが)

これを簡単に解決する方法はないようなので、関数を作った。
┌──────────────────────────────────────┐
│CSV結果 = 引数をCSV結合(文字列1, 文字列2, 文字列3)                          │
├──────────────────────────────────────┤
│Public Function 引数をCSV結合(ParamArray 配列()) As String                  │
│    Dim 結果 As Variant, 値 As Variant                                      │
│    For Each 値 In 配列                                                     │
│        If 値 <> "" Then                                                    │
│            Call 配列末尾追加(結果, 値)                                     │
│        End If                                                              │
│    Next 値                                                                 │
│    If IsArray(結果) Then                                                   │
│        引数をCSV結合 = Join(結果, ",")                                     │
│    Else                                                                    │
│        引数をCSV結合 = ""                                                  │
│    End If                                                                  │
│End Function                                                                │
├──────────────────────────────────────┤
│Private Sub 配列末尾追加(ByRef 配列 As Variant, _                           │
│                         ByVal 追加要素 As Variant)                         │
│    On Error GoTo l_Catch                                                   │
│    If IsArray(配列) Then                                                   │
│        ReDim Preserve 配列(UBound(配列) + 1)                               │
│    Else                                                                    │
│        ReDim 配列(0)                                                       │
│    End If                                                                  │
│    配列(UBound(配列)) = 追加要素                                           │
│    Exit Sub                                                                │
│l_Catch:                                                                    │
│    ReDim 配列(0)                                                           │
│    配列(UBound(配列)) = 追加要素                                           │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
JavaScript/オブジェクト指向
2019年08月22日
連想配列でクラスを代用するには以下の方法がある。
┌──────────────────────────────────────┐
│const オブジェクト = {                                                      │
│    メンバ変数  :値,                                                        │
│    メソッド    :function(引数) {                                           │
│                     return 引数 * this.メンバ変数;                         │
│                 },                                                         │
│    メソッド    :引数 => {                                                  │
│                     return 引数 * this.メンバ変数;                         │
│                 },                                                         │
│    メソッド(引数) {                                                        │
│        return 引数 * this.メンバ変数;                                      │
│    }                                                                       │
│};                                                                          │
└──────────────────────────────────────┘
ES2015からはクラスが導入された。
┌──────────────────────────────────────┐
│class クラス {                                                              │
│////メンバ変数 = 値;  ←これはNG                                            │
│    constructor(引数) {                                                     │
│        this.メンバ変数 = 引数;                                             │
│    }                                                                       │
│    メソッド() {                                                            │
│        return this.メンバ変数;                                             │
│    }                                                                       │
│}                                                                           │
├──────────────────────────────────────┤
│const インスタンス = new クラス(引数);                                      │
│インスタンス.メソッド();                                                    │
├──────────────────────────────────────┤
│class 継承クラス extends クラス {                                           │
│    constructor(引数) {                                                     │
│        super();                                                            │
│    }                                                                       │
│}                                                                           │
└──────────────────────────────────────┘
分類:JavaScript
ExcelVBA/コンボボックスでユーザフォーム起動
2019年08月20日
┌──────────────────────────────────────┐
│Private Sub ComboBox_Change()                                               │
│    UserForm.Show                                                           │
│End Sub                                                                     │
└──────────────────────────────────────┘
コンボボックスの選択(変更)とともにユーザフォームを起動しようとした場合
コンボボックスが開いたままとなり、さらに選択(変更)できてしまい
エラーを誘発してしまう。

コンボボックスの選択が確定した後にユーザフォームを起動すればよいのだが
それに適うイベントというのが見当たらない

仕方がないので、代案。
敢えてフォーカスを外して閉じてからユーザフォームを起動すればよい。
┌──────────────────────────────────────┐
│Private Sub ComboBox_Change()                                               │
│    Me.Cells(1, 1).Activate     'メニューを閉じるため別にフォーカスをあてる │
│    Me.ComboBox.Activate        '  戻す                                     │
│    UserForm.Show                                                           │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
MSSQL/文字列比較の末尾スペース
2019年08月11日
MSSQLでは文字列比較時に末尾のスペースを無視するのだ。
つまり可変長を固定長と比較しても、中身が同じだったら真になるのである。

ちなみに以下で確認すると「真」になる。
┌──────────────────────────────────────┐
│SELECT CASE                                                                 │
│         WHEN 'a' = 'a ' THEN '真'                                          │
│         ELSE                 '偽'                                          │
│       END AS [テスト];                                                     │
└──────────────────────────────────────┘

文字数としても末尾は除去されている。
┌──────────────────────────────────────┐
│SELECT LEN('a ');                                                   →1(≠2)│
└──────────────────────────────────────┘
分類:MSSQL
ExcelVBA/DB読込時の進捗表示
2019年08月10日
以下のような感じ。
┌──────────────────────────────────────┐
│Dim データベース As New ADODB.Connection                                    │
│Dim テーブル As New ADODB.Recordset                                         │
├──────────────────────────────────────┤
│With データベース                                                           │
│    .ConnectionString = 接続情報                                            │
│    .CursorLocation = adOpenStatic  ' .RecordCountのために静的カーソルを選択│
│    .Open                                                                   │
│End With                                                                    │
├──────────────────────────────────────┤
│Do Until テーブル.EOF                                                       │
│    DoEvents                                                                │
│    Application.StatusBar = "進捗率=" & テーブル.AbsolutePosition _        │
│                                 & "/" & テーブル.RecordCount               │
│Loop                                                                        │
│Application.StatusBar = False                                               │
└──────────────────────────────────────┘
DBオープン時に静的カーソル(adOpenStatic)を選択しないと、
レコード総数(.RecordCount)が取得できないので注意。
現在の位置(.AbsolutePosition)と対比させれば進捗率が出せる。
(上記例は数式を表示しているだけ)
分類:ExcelVBA
ExcelVBA/キーブレイクの例
2019年08月09日
こんな感じ。
┌──────────────────────────────────────┐
│Dim y As Long                                                               │
│Dim oldキー1 As String, newキー1 As String                                  │
│Dim oldキー2 As String, newキー2 As String                                  │
│Dim 総計 As Long, 中計 As Long, 中計 As Long                                │
├──────────────────────────────────────┤
│y = 1                                                                       │
│総計 = 0                                                                    │
│Do Until テーブル.EOF                                                       │
│    '-----------------------------------------------------------------------│
│    中計 = 0                                                                │
│    '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -│
│    oldキー1 = テーブル.Fields("キー1").Value                               │
│    Do                                                                      │
│        '-------------------------------------------------------------------│
│        小計 = 0                                                            │
│        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -│
│        oldキー2 = テーブル.Fields("キー2").Value                           │
│        Do                                                                  │
│            小計 = 小計 + テーブル.Fields("値").Value                       │
│            中計 = 中計 + テーブル.Fields("値").Value                       │
│            総計 = 総計 + テーブル.Fields("値").Value                       │
│            テーブル.MoveNext                                               │
│            If Not テーブル.EOF Then                                        │
│                newキー1 = テーブル.Fields("キー1").Value                   │
│                newキー2 = テーブル.Fields("キー2").Value                   │
│            End If                                                          │
│        Loop Until テーブル.EOF _                                           │
│                Or newキー1 <> oldキー1 _                                   │
│                Or newキー2 <> oldキー2                                     │
│        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -│
│        シート.Cells(y, 1).Value = 小計                                     │
│        y = y + 1                                                           │
│        '-------------------------------------------------------------------│
│    Loop Until テーブル.EOF _                                               │
│            Or newキー1 <> oldキー1                                         │
│    '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -│
│    シート.Cells(y, 1).Value = 中計                                         │
│    y = y + 1                                                               │
│    '-----------------------------------------------------------------------│
│Loop                                                                        │
│シート.Cells(y, 1).Value = 総計                                             │
└──────────────────────────────────────┘
VBAの場合「OrElse」がないので、EOFとなった時に
直接「テーブル.Fields("キー1").Value」などをキーブレイク条件に記載すると
「テーブル.EOF(= True)」を飛び越えて参照しにいってしまうためエラーとなる。
この点に注意だ。 
分類:ExcelVBA
前へ 1 … 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 … 156 次へ