MW211 EXIT

devlog
ExcelVBA/勝手に折り返される
2017年12月29日
【現象】
  「セルの書式設定」で「折り返して全体を表示する」のチェックを外して
  無効にしたのに、なぜか文字列を出力すると、
「折り返して全体を表示する」のチェックが復活して、折り返して表示される。

【原因】
  出力した文字列に改行コード(LF)が含まれているため。
分類:ExcelVBA
ExcelVBA/セル範囲の入力(ユーザフォーム編)
2017年12月28日
ユーザフォームでセル範囲を入力させるには
「RefEdit」というコントロール(オブジェクト)を使う。
これはフォームのツールボックスに既定で存在する。

以下のようなイベント関数ができる。(「RefEdit1」の部分はオブジェクト名に依存)
┌──────────────────────────────────────┐
│Private Sub RefEdit1_BeforeDragOver(Cancel As Boolean,                      │
│                                    ByVal Data As MSForms.DataObject,       │
│                                    ByVal x As stdole.OLE_XPOS_CONTAINER,   │
│                                    ByVal y As stdole.OLE_YPOS_CONTAINER,   │
│                                    ByVal DragState As MSForms.fmDragState, │
│                                    Effect As MSForms.fmDropEffect,         │
│                                    ByVal Shift As Integer)                 │
│End Sub                                                                     │
└──────────────────────────────────────┘

そんでもってボタンオブジェクト(「CommandButton1」の部分はオブジェクト名に依存)で
以下のように参照してあげればよい。
┌──────────────────────────────────────┐
│Private Sub CommandButton1_Click()                                          │
│    Dim 範囲 As Range                                                       │
│    Set 範囲 = Range(RefEdit1.Value)                                        │
│    MsgBox 範囲.Rows.Count  ' 選択した(範囲の)行数はいくつ?                │
│End Sub                                                                     │
└──────────────────────────────────────┘
「RefEdit」オブジェクトの値が範囲(Range)相当となる。
分類:ExcelVBA
ExcelVBA/セル範囲の入力
2017年12月27日
Application.InputBox()を使って、ユーザにセルを選択させる方法。
┌──────────────────────────────────────┐
│Dim 指定範囲 As Range                                                       │
│On Error Resume Next                                                        │
│Set 指定範囲 = Application.InputBox("セルを選択してください", Type:=8)      │
│On Error GoTo 0                                                             │
│If 指定範囲 Is Nothing Then                                                 │
│    MsgBox "キャンセルされました"                                           │
│    Exit Sub                                                                │
│End If                                                                      │
│指定範囲.Interior.Color = RGB(0, 255, 0)                                    │
└──────────────────────────────────────┘
「Type:=8」だとセル選択となる。
なお、キャンセルの場合、戻り値がなくエラーとなるが
回避方法は「On Error Resume Next」となってしまう。
分類:ExcelVBA
ExcelVBA/Worksheet_ChangeのTarget
2017年12月26日
┌──────────────────────────────────────┐
│Private Sub Worksheet_Change(ByVal Target As Range)                         │
│    If Target.Value = "×" Then                                             │
│        MsgBox "入力エラー", vbCritical                                     │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
こんな感じで入力チェックを実装した場合、
コピー&ペーストで複数セルを同時入力された場合にエラーとなってしまう。
→試にタブ区切りで二単語以上をつないだものをまとめてコピぺしてみるとよい

ということで、Worksheet_ChangeのTargetは
複数セル同時入力されることを見越して、Foreach文にしておくのがよい。
┌──────────────────────────────────────┐
│Private Sub Worksheet_Change(ByVal Target As Range)                         │
│    Dim セル As Range                                                       │
│    For Each セル In Target                                                 │
│        If セル.Value = "×" Then                                           │
│            MsgBox "入力エラー", vbCritical                                 │
│        End If                                                              │
│    Next セル                                                               │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/入力チェックの後始末
2017年12月25日
入力チェックしたはいいが、警告ダイアログだけ出して、
不正な入力を野放しにしてはいけない(意味がない)。

クリアしちまえばいいのだろうが、
上書する前の元の値までなくなってしまうのはいただけない。

ということで、元の値に戻す方法。UNDOを使う。
┌──────────────────────────────────────┐
│Private Sub Worksheet_Change(ByVal Target As Range)                         │
│    If Target.Value <> "" Then                                              │
│        If Target.Value <> "御意" Then                                      │
│            MsgBox "入力エラー", vbCritical                                 │
│            Application.EnableEvents = False                                │
│            Application.Undo                                                │
│            Application.EnableEvents = True                                 │
│        End If                                                              │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
こんな感じ(「御意」と入力しないと元に戻される)。

まず、「Worksheet_Change()」は入力後のイベントのため
入力前の値を保持できていない。
そこで、UNDO「Application.Undo」。

但し、「Application.Undo」はイベントを発生させてしまうので、
「Application.EnableEvents = False」でイベント取得を無効にしてあげないと
永久ループとなってしまう。
→試しに、これを外して実行してみるとよくわかる(永久ループ)。
  ちなみに永久ループになったら焦らず「Ctrl+Pause」だ!
分類:ExcelVBA
SQL/更新元がMAX()だったら
2017年12月21日
素朴な疑問。
  ┌─┐                             ┌─────┐    ┌─────┐
  │ 1│                             │ 3+ 1= 4│    │ 3+ 1= 4│
  ├─┤                             ├─────┤    ├─────┤
  │ 2│を、MAX()+自身で更新したら  │ 3+ 2= 5│?  │ 4+ 2= 6│?
  ├─┤                             ├─────┤    ├─────┤
  │ 3│                             │ 3+ 3= 6│    │ 6+ 3= 9│
  └─┘                             └─────┘    └─────┘
都度都度MAX()結果が変わって雪だるま式に増えたりしないのだろうか?


やってみた(MSSQLで)。

まず、以下を準備。
┌──────────────────────────────────────┐
│CREATE TABLE [表] (                                                         │
│    [列] [int] NULL,                                                    ┌─┐
│);                                                                      │ 1│
├────────────────────────────────────├─┤
│INSERT INTO [表] VALUES (1);                                            │ 2│
│INSERT INTO [表] VALUES (2);                                            ├─┤
│INSERT INTO [表] VALUES (3);                                            │ 3│
└────────────────────────────────────└─┘

で、以下はエラー。
┌──────────────────────────────────────┐
│UPDATE [表]                                                                 │
│    SET [列] = MAX([列]) + [列];                                            │
├──────────────────────────────────────┤
│UPDATE [表]                                                                 │
│    SET [列] =  MAX([列])  + [列]                                           │
│    FROM [表];                                                              │
└──────────────────────────────────────┘
→「UPDATEステートメントのSETリストには集計を含めることはできません。」

以下はできた。
┌──────────────────────────────────────┐
│UPDATE [表]                                                                 │
│    SET [列] = (SELECT MAX([列]) FROM [表]) + [列];                         │
└──────────────────────────────────────┘
結果は…
┌─┐
│ 4│
├─┤
│ 5│
├─┤
│ 6│
└─┘
雪だるま式には増えないみたい。(期待した結果ではある)

あくまで、副問合せの結果が確定した上で、
主問合せ(UPDATE)が始まるって感じなのかな。
(最初のエラーのやつは本来は雪だるま式だったのかもしれない)
分類:SQL
jQuery/AND条件の代替(filterメソッド)
2017年12月15日
┌──────────────────────────────────────┐
│$('①,②')                                                         // ①OR②│
└──────────────────────────────────────┘
上記のようなOR条件のセレクタにAND条件を加味させたい場合、以下のようになる。
┌──────────────────────────────────────┐
│$('③①,③②')                                       // (③AND①)OR(③AND②)│
└──────────────────────────────────────┘
これでは、ちょっと冗長的(これが複合していった場合複雑になる)といった場合には
filterメソッドを使って以下のように書き替えることが可能である。
┌──────────────────────────────────────┐
│$('③').filter('①,②')                                     // ③AND(①OR②)│
├──────────────────────────────────────┤
│$('①,②').filter('③')                                     // (①OR②)AND③│
└──────────────────────────────────────┘
分類:jQuery
ExcelVBA/Type(3)
2017年12月14日
Type(構造体)はJoin()できない
┌─┬────────────────────────────────────┐
│○│文字列 = Join(配列, ",")                                                │
├─┼────────────────────────────────────┤
│×│文字列 = Join(構造体, ",")                                              │
└─┴────────────────────────────────────┘
構造体を配列化できれば、Join()できそうなのだが、その術がなさそうだ。
よって、CSVデータは配列で扱った方がよさそうな感じである。
分類:ExcelVBA
ExcelVBA/Type(2)
2017年12月13日
Type(構造体)は配列化できる。
┌─────┬────────────────────────────────┐
│Typeの定義│Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │End Type                                                        │
├─────┼────────────────────────────────┤
│Typeの使用│Dim 配列構造体インスタンス(1 To 3) As 構造体                    │
│          │構造体インスタンス(1).列1 = 0;                                  │
│          │MsgBox 構造体インスタンス(1).列1                                │
└─────┴────────────────────────────────┘
もちろん動的配列もOK。

構造体の入れ子もできる。(サブ側を先に宣言しないとエラーとなるので注意)
┌─────┬────────────────────────────────┐
│Typeの定義│Type サブ構造体                                                 │
│          │    副列1        As Long                                        │
│          │    副列2        As String                                      │
│          │End Type                                                        │
│          │Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │    列3          As サブ構造体                                  │
│          │End Type                                                        │
└─────┴────────────────────────────────┘
さらには動的配列にもできる。
┌─────┬────────────────────────────────┐
│Typeの定義│Type サブ構造体                                                 │
│          │    副列1        As Long                                        │
│          │    副列2        As String                                      │
│          │End Type                                                        │
│          │Type 構造体                                                     │
│          │    列1          As Long                                        │
│          │    列2          As String                                      │
│          │    列3()        As サブ構造体                                  │
│          │End Type                                                        │
└─────┴────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/クリップボード
2017年12月12日
クリップボードの制御には、参照設定「Microsoft Forms 2.0 Object Library」が必要。

「,」付きの数値をコピーした場合に、
クリップボード上では「,」を除外する方法を模索中。
┌──────────────────────────────────────┐
│Option Explicit                                                             │
│Private Sub Worksheet_SelectionChange(ByVal Target As Range)                │
│    Dim myData As New DataObject                                            │
│    On Error Resume Next                                                    │
│    myData.GetFromClipboard                                                 │
│    myData.SetText Replace(myData.GetText, ",", "")                         │
│    myData.PutInClipboard                                                   │
│End Sub                                                                     │
└──────────────────────────────────────┘
こんな感じか?さてどのイベントで拾おうか。。。

ちなみにショートカットキー「ctrl+c」を登録して
以下の関数を呼び出すというのもありかも。
┌──────────────────────────────────────┐
│Option Explicit                                                             │
│Public Sub ctrlc()                                                          │
│    Dim clipBoard As New DataObject                                         │
│    On Error Resume Next                                                    │
│    clipBoard.SetText Replace(ActiveCell.Value, ",", "")                    │
│    clipBoard.PutInClipboard                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
前へ 1 2 次へ