MW211 EXIT

devlog
ExcelVBA/サブウインドウのみの入力にする
2014年12月23日
サブウインドウ(UserFrom)以外の入力ができなくするには、
以下の様にパラメータを設定すればよい。
┌──────────────────────────────────────┐
│UserFrom.ShowModal = True                                                   │
└──────────────────────────────────────┘

逆に、本体のExcelシートが入力できる余地を残すのは以下の設定となる。
┌──────────────────────────────────────┐
│UserFrom.ShowModal = False                                                  │
└──────────────────────────────────────┘

但し、同一サブウインドウを続けて開くと厄介なことになりそうなので
以下のようなガードを入れたりする必要が出てくる。
┌──────────────────────────────────────┐
│If UserForms.Count = 0 Then                                                 │
│    UserForm.Show                                                           │
│End If                                                                      │
└──────────────────────────────────────┘
ま、利用者の柔軟性が高い分、考慮も必要だということだ。
分類:ExcelVBA
MSSQL/トランザクションのネスト
2014年12月22日
トランザクションをネストして、ロールバックとかしてしまうと
ネスト関係なく全てロールバックしてしまうので注意。
┌───────────────┐
│BEGIN TRY                     │
│    BEGIN TRANSACTION         │
│      ┌─────────────┐
│      │BEGIN TRY                 │
│      │    BEGIN TRANSACTION     │
│      │    COMMIT TRANSACTION    │
│      │END TRY                   │
│      │BEGIN CATCH               │
│      │    ROLLBACK TRANSACTION  ──┐全てをロールバックしてしまう
│      │    RETURN ERROR_NUMBER() │  │
│      │END CATCH                 │  │
│      │RETURN (0);               │  │
│      └─────────────┘  │
│    COMMIT TRANSACTION        │      │
│END TRY                       │      │
│BEGIN CATCH                   │      │
│    ROLLBACK TRANSACTION      ←───┘二重ロールバック扱いでエラーとなる
│    RETURN ERROR_NUMBER()     │
│END CATCH                     │
│RETURN (0);                   │
└───────────────┘
ネストは基本使わない方が賢明のようだ。
もしくはセーブポイント(SAVE TRANSACTION)を使うとか。
分類:MSSQL
Windows/致命的エラーの戻り値
2014年12月21日
「%ERRORLEVEL%」で直前に実行された結果を戻り値として取得できるが、
根本的な誤りを犯した場合の戻り値は以下の様になる。
┌─────┬────────────────────────────────┐
│戻り値    │3                                                               │
├─────┼────────────────────────────────┤
│winerror.h│ERROR_PATH_NOT_FOUND                                            │
├─────┼────────────────────────────────┤
│メッセージ│指定されたパスが見つかりません。                                │
├─────┼────────────────────────────────┤
│原因      │・存在しないパス(の実行ファイル)を実行した場合(*1)              │
│          │  *1:フルパスの中に「\」を含んでいる場合                       │
└─────┴────────────────────────────────┘
┌─────┬────────────────────────────────┐
│戻り値    │9009                                                            │
├─────┼────────────────────────────────┤
│winerror.h│DNS_ERROR_RCODE_NOTAUTH                                         │
├─────┼────────────────────────────────┤
│メッセージ│'■' は、内部コマンドまたは外部コマンド、                       │
│          │操作可能なプログラムまたはバッチファイルとして                  │
│          │認識されていません。                                            │
├─────┼────────────────────────────────┤
│原因      │・存在しない実行ファイルを実行した場合                          │
│          │  (=適当な文字列をコマンド入力した場合(但し「\」を含むと「3」))│
└─────┴────────────────────────────────┘
分類:Windows
Excel/入力規則の確認
2014年12月20日
データの入力規則を設定したものの、どこのセルに設定したのか忘れてしまった場合
それを検索する方法。

ホーム>検索と選択>ジャンプ
#ショートカットキーから「CTRL+G」→「セル選択」で
┌────────────────────┐
│選択オプション                          │
├────────────────────┤
│                                        │
│                                        │
│                                        │
│                      ●データの入力規則│
│                        ●すべて        │
│                        ○同じ入力規則  │
└────────────────────┘
分類:Excel
Excel/入力文字数制限
2014年12月19日
セルの入力文字数を制限するには、データの入力規則で設定すればよい。

データ>データの入力規則>データの入力規則
┌────────────────────────┐
│データの入力規則                                │
├────────────────────────┤
│┌──┐                                        │
││設定│                                        │
││    └───────────────────┐│
││条件の設定                                  ││
││  入力値の種類                              ││
││  ┌────────┬─┐                  ││
││  │文字列(長さ指定)│▼│  □空白を無視する││
││  └────────┴─┘                  ││
││  データ                                    ││
││  ┌────────┬─┐                  ││
││  │次の値以下      │▼│                  ││
││  └────────┴─┘                  ││
││  最大値                                    ││
││  ┌────────────┬─┐          ││
││  │16                      │  │          ││
││  └────────────┴─┘          ││
│└──────────────────────┘│
│┌──────┐    ┌─────┐┌─────┐│
││すべてクリア│    │    OK    ││キャンセル││
│└──────┘    └─────┘└─────┘│
└────────────────────────┘
分類:Excel
MSSQL/代入で該当なし例外対策
2014年12月18日
例えば、ストアドプロシージャにて、以下のような代入文とした場合…。
┌──────────────────────────────────────┐
│DECLARE @変数  int                                                          │
├──────────────────────────────────────┤
│SELECT @変数 = [列]                                                         │
│    FROM [表]                                                               │
│    WHERE [抽出条件列] = 値;                                                │
└──────────────────────────────────────┘
WHERE条件で該当がないと、例外が発生してしまう。

LEFT JOINみたいに、該当なしは「NULL」になってくれるとありがたい場合、

ということで、以下のようなダミー表にLEFT JOINしてあげる。
┌──────────────────────────────────────┐
│DECLARE @変数  int                                                          │
├──────────────────────────────────────┤
│SELECT @変数 = [表].[列]                                                    │
│    FROM (SELECT 1 AS [ダミー列]) AS [ダミー表]                             │
│        LEFT JOIN (                                                         │
│            SELECT [列]                                                     │
│                FROM [表]                                                   │
│                WHERE [抽出条件列] = 値                                     │
│        ) AS [表]                                                           │
│          ON 1 = 1                                                          │
└──────────────────────────────────────┘
ま、これで、実現できることは実現できるのだが、これではちょっと美しくない。

もっと、シンプルに書けるのは以下の通り。
┌──────────────────────────────────────┐
│DECLARE @変数  int                                                          │
├──────────────────────────────────────┤
│SELECT @変数 = (                                                            │
│    SELECT [列]                                                             │
│        FROM [表]                                                           │
│        WHERE [抽出条件列] = 値                                             │
│);                                                                          │
└──────────────────────────────────────┘
分類:MSSQL
ExcelVBA/行列をまるっと移動
2014年12月16日
行列を16×16の範囲でまるっと移動するマクロ。
┌──────────────────────────────────────┐
│Sub 行をまるっと上へ移動()                                                  │
│    With ActiveCell                                                         │
│        If .Row > 1 Then                                                    │
│        .EntireRow.Cut                                                      │
│        .Offset(-1, 0).EntireRow.Insert Shift:=xlDown                       │
│        End If                                                              │
│    End With                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│Sub 行をまるっと下へ移動()                                                  │
│    With ActiveCell                                                         │
│        If .Row < 16 Then                                                   │
│        .EntireRow.Cut                                                      │
│        .Offset(2, 0).EntireRow.Insert Shift:=xlDown                        │
│        End If                                                              │
│    End With                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│Sub 列をまるっと左へ移動()                                                  │
│    With ActiveCell                                                         │
│        If .Column > 1 Then                                                 │
│        .EntireColumn.Cut                                                   │
│        .Offset(0, -1).EntireColumn.Insert Shift:=xlToRight                 │
│        End If                                                              │
│    End With                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│Sub 列をまるっと右へ移動()                                                  │
│    With ActiveCell                                                         │
│        If .Column < 16 Then                                                │
│            .EntireColumn.Cut                                               │
│            .Offset(0, 2).EntireColumn.Insert Shift:=xlToRight              │
│        End If                                                              │
│    End With                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
MSSQL/マッチング・後編
2014年12月15日
MERGE文はあきらめて、地道にINSERT・UPDATE文でやっちまうのが手っ取り早い。

「変更→削除→追加」の順が妥当なようだ。

ということで、以下のような感じで。
┌──────────────────────────────────────┐
│-- 変更                                                                     │
│UPDATE [旧表]                                                               │
│    SET [列]       = [新表].[列],                                           │
│        [更新日時] = getdate()                                              │
│    FROM [旧表]                                                             │
│        INNER JOIN [新表]                                                   │
│          ON  [新表].[キー] =  [旧表].[キー]                                │
│          AND [新表].[列]   <> [旧表].[列]                                  │
│    WHERE [旧表].[削除済フラグ] = 0;                                        │
├──────────────────────────────────────┤
│-- 削除                                                                     │
│UPDATE [旧表]                                                               │
│    SET [削除済フラグ] = 1,                                                 │
│        [更新日時]     = getdate()                                          │
│    WHERE [旧表].[削除済フラグ] = 0                                         │
│      AND NOT EXISTS (                                                      │
│              SELECT *                                                      │
│                  FROM [新表]                                               │
│                  WHERE [新表].[キー]         = [旧表].[キー]               │
│                    AND [新表].[削除済フラグ] = 0                           │
│          );                                                                │
├──────────────────────────────────────┤
│-- 追加                                                                     │
│INSERT INTO [旧表] (                                                        │
│        [キー],                                                             │
│        [列],                                                               │
│        [更新日時]                                                          │
│    )                                                                       │
│    SELECT [新表].[キー],                                                   │
│           [新表].[列],                                                     │
│           getdate()                                                        │
│        FROM [新表]                                                         │
│        WHERE [新表].[削除済フラグ] = 0                                     │
│          AND NOT EXISTS (                                                  │
│                  SELECT *                                                  │
│                      FROM [旧表] AS [追加先]                               │
│                      WHERE [追加先].[キー]         = [新表].[キー]         │
│                        AND [追加先].[削除済フラグ] = 0                     │
│              );                                                            │
└──────────────────────────────────────┘
分類:MSSQL
MSSQL/マッチング・前編
2014年12月14日
旧表に新表を突合させ、旧表がなければ追加、旧表があれば更新、
逆に新表になければ削除という典型的なマッチング処理がある。

これはMERGE文で一発できる。
┌──────────────────────────────────────┐
│MERGE INTO [旧表]                                                           │
│    USING [新表]                                                            │
│      ON  [旧表].キー = [新表].[キー]                                       │
│    WHEN MATCHED THEN                                                       │
│        UPDATE SET [列] = [新表].[列]                                       │
│    WHEN NOT MATCHED BY TARGET THEN                                         │
│        INSERT (                                                            │
│                [キー],                                                     │
│                [列]                                                        │
│            ) VALUES (                                                      │
│                [新表].[キー],                                              │
│                [新表].[列]                                                 │
│            )                                                               │
│    WHEN NOT MATCHED BY SOURCE THEN                                         │
│        DELETE;                                                             │
└──────────────────────────────────────┘
しかし、これに以下の条件が付いた場合、途端に対応できなくなる
  ・削除は直接DELETEするのではなく、削除済フラグを1にすることで行う
  ・変更の場合、更新する列に差分がある時のみ行う
    #同時に更新日時を更新することを想定(差分がない場合は更新したくない)

せいぜい対応できるのは、新表側を抽出することぐらいのみ。
┌──────────────────────────────────────┐
│MERGE INTO [旧表]                                                           │
│    USING (SELECT * FROM [新表] WHERE [削除済フラグ] = 0) AS [新表]         │
│      ON  [旧表].キー = [新表].[キー]                                       │
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
└──────────────────────────────────────┘

まず、旧表側(更新先)を抽出することはできない。
┌──────────────────────────────────────┐
│MERGE INTO (SELECT * FROM [旧表] WHERE [削除済フラグ] = 0) AS [旧表]        │
│    USING [新表]                                                            │
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
└──────────────────────────────────────┘

IF文を挟むこともできない。
┌──────────────────────────────────────┐
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
│    WHEN MATCHED THEN                                                       │
│        IF [列] <> [新表].[列]                                              │
│            UPDATE SET [列] = [新表].[列]                                   │
└──────────────────────────────────────┘

MERGE文は本格的なマッチング処理ではなく、
ミラーリング的なところに用いるものなのだろう。

ということで、その解決策は後編へ続く。。。
分類:MSSQL
MSSQL/ADODBで更新件数取得
2014年12月13日
ADODBで以下のような感じで、「.Execute」の第二引数で更新件数を取得できる。
┌──────────────────────────────────────┐
│Private データベース As New ADODB.Connection                                │
├──────────────────────────────────────┤
│データベース.Execute 更新SQL文, 更新件数                                    │
└──────────────────────────────────────┘
でも、トリガが設定されている場合、
トリガで作用したSQL文の結果が取得されてしまう。

これを抑止するのは、トリガの結果を戻さないようにする。
以下のような感じで冒頭で「SET NOCOUNT ON;」を実行して抑止すればよい。
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[トリガ] ON [DB].[dbo].[表]                            │
│    AFTER UPDATE                                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    SET NOCOUNT ON;                                                         │
│    ~SQL文~                                                               │
│END;                                                                        │
└──────────────────────────────────────┘
もちろん、トリガの呼び元には抑止の影響がないので、
.Executeで実行したSQL文の更新件数が確実に取得できる。
分類:MSSQL
前へ 1 … 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 … 156 次へ