MW211 EXIT

devlog
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
ExcelVBA/テキストボックスの自動伸縮
2019年07月30日
テキストボックスのサイズを自動で可変にする設定は以下の通り。
┌──────────────────────────────────────┐
│With シート.TextBox                                                         │
│    .AutoSize = True                                                        │
│    .MultiLine = True                                                       │
│    .WordWrap = False                                                       │
│End With                                                                    │
└──────────────────────────────────────┘
但し、一旦にアクティブにしないと再計算されないようなので
以下のようにアクティブにしてあげる。
┌──────────────────────────────────────┐
│With シート.TextBox                                                         │
│    .Activate                                                               │
│    .SelStart = 0                                                           │
│End With                                                                    │
│シート.Cells(1, 1).Activate                                                 │
└──────────────────────────────────────┘

なお、固定に戻すのは以下のような感じ。(.Heightと.Widthの値は任意)
┌──────────────────────────────────────┐
│With シート.TextBox                                                         │
│    .AutoSize = False                                                       │
│    .MultiLine = True                                                       │
│    .WordWrap = True                                                        │
│    .Height = 100                                                           │
│    .Width = 100                                                            │
│End With                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
PHP/APIクライアントテスト用サーバ
2019年07月02日
クライアント側からPOSTした内容をそのまま返すサーバ。
┌──────────────────────────────────────┐
│echo print_r(json_decode(file_get_contents('php://input'), TRUE), TRUE);    │
└──────────────────────────────────────┘
分類:PHP
Oracle/掛け算(総積)
2019年06月26日
各行の値を足し算する(総和)のは以下の通り、基本中の基本だ。
┌──────────────────────────────────────┐
│SELECT SUM("数")                                                            │
│    FROM "表";                                                              │
└──────────────────────────────────────┘

じゃ、掛け算にできるか?(総積)
┌──────────────────────────────────────┐
│SELECT ROUND(EXP(SUM(LN("数"))))                                            │
│    FROM "表";                                                              │
└──────────────────────────────────────┘
こんな感じでてきてしまうのである。

自前の表を使って確認してみると確かに「2×3=6」という結果になる
┌──────────────────────────────────────┐
│WITH "表" AS (                                                              │
│         SELECT *                                                           │
│             FROM (                                                         │
│                           SELECT 2 AS "数" FROM DUAL                       │
│                 UNION ALL SELECT 3 AS "数" FROM DUAL                       │
│             )                                                              │
│     )                                                                      │
│SELECT ROUND(EXP(SUM(LN("数"))))                                            │
│    FROM "表";                                                              │
└──────────────────────────────────────┘

やっていることは以下の通り
(1) 「LN()」で一旦、自然対数(log)に変換する
(2) 「SUM()」でそれらを足し算する(総和を求める)
(3) その結果を「EXP()」で元に戻す
(4) 計算の過程で端数(ほんの小さい誤差)が出るので「ROUND()」で四捨五入し調整
分類:Oracle
MSSQL/プログラムを実行する
2019年05月30日
┬──────────────────────────────────────┬
│「xp_cmdshell」を実行できるようにする                                       │
┴──────────────────────────────────────┴
  ┌────────────────────────────────────┐
  │EXEC xp_cmdshell …                                                     │
  └────────────────────────────────────┘
  上記のような「EXEC xp_cmdshell」文を実行した場合に以下のエラーが出る
  ┌────────────────────────────────────┐
  │メッセージ 15281、レベル 16、状態 1、プロシージャ xp_cmdshell、行 1     │
  │SQL Server によって、コンポーネント 'xp_cmdshell' の                    │
  │プロシージャ 'sys.xp_cmdshell' に対するアクセスがブロックされました。   │
  │このサーバーのセキュリティ構成で、                                      │
  │このコンポーネントが OFF に設定されているためです。                     │
  │システム管理者は sp_configure を使用して、                              │
  │'xp_cmdshell' の使用を有効にできます。                                  │
  │'xp_cmdshell' を有効にする手順の詳細については、                        │
  │SQL Server オンライン ブックで、'xp_cmdshell' を検索してください。      │
  └────────────────────────────────────┘
  これは既定では実行制限がかかっているからである
┌[注意]───────────────────────────────────┐
│既定で実行制限がかかっているというのは                                      │
│これから先の設定変更を行うとMSSQLからプログラム実行ができるため             │
│ある意味、如何様な悪さでもし放題ということになる                            │
│よって、SQLインジェクション対策には十分注意された上で臨んでいただきたい     │
└──────────────────────────────────────┘
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  そこでその設定変更(緩和)方法
  以下二組のコマンドを続けて実行する
  ┌────────────────────────────────────┐
  │EXEC sp_configure 'show advanced options', 1;                           │
  │RECONFIGURE;                                                            │
  │┌────────────────────────────────────┐
  ││構成オプション 'show advanced options' が 0 から 1 に変更されました。   │
  ││RECONFIGURE ステートメントを実行してインストールしてください。          │
  │└────────────────────────────────────┘
  ├────────────────────────────────────┤
  │EXEC sp_configure 'xp_cmdshell', 1;                                     │
  │RECONFIGURE;                                                            │
  │┌────────────────────────────────────┐
  ││構成オプション 'xp_cmdshell' が 0 から 1 に変更されました。             │
  ││RECONFIGURE ステートメントを実行してインストールしてください。          │
  │└────────────────────────────────────┘
  └────────────────────────────────────┘
  なお、二つ目だけをいきなり実行すると以下のエラーとなるので注意
  ┌────────────────────────────────────┐
  │メッセージ 15123、レベル 16、状態 1、プロシージャ sp_configure、行 62   │
  │構成オプション 'xp_cmdshell' が存在しないか、                           │
  │詳細構成オプションの可能性があります。                                  │
  └────────────────────────────────────┘
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  なお、別案として、以下でも同等なことができる
  ┌────────────────────────────────────┐
  │「Microsoft SQL Server Management Studio」におけるツリー上のサーバの    │
  │右クリックメニュー「ファセット」を選択                                  │
  │┌─────────────────────┐                          │
  ││ファセットの表示                          │                          │
  │├──┬──────────────────┤                          │
  ││全般│          ┌───────────┐│                          │
  ││    │ファセット│サーバーセキュリティー││                          │
  ││    │          └───────────┘│                          │
  ││    │┌───────────┬────┐│                          │
  ││    ││XPCmdShellEnabled     │False   ││→「True」にする          │
  ││    │└───────────┴────┘│                          │
  └────────────────────────────────────┘
  GUIで「XPCmdShellEnabled」を「True」に設定すればよい
┬──────────────────────────────────────┬
│「xp_cmdshell」の実行                                                       │
┴──────────────────────────────────────┴
  通常のコマンドを「EXEC xp_cmdshell」の後に文字列と記述すれば実行すればよい
  例えば以下のような感じ
  ┌────────────────────────────────────┐
  │EXEC xp_cmdshell 'dir'                                                  │
  └────────────────────────────────────┘
  処理結果として、結果が行ごとのレコードとして返却される
  また、以下のように標準出力を変えてあげることもできる(通常のコマンドと同様)
  ┌────────────────────────────────────┐
  │EXEC xp_cmdshell 'dir > D:\work\test.txt'                               │
  └────────────────────────────────────┘
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  なお、正常終了(0)か否かの戻り値が返るので、これを捕捉することもできる
  ┌────────────────────────────────────┐
  │DECLARE @ret int;                                                       │
  │EXEC @ret = xp_cmdshell 'dir'                                           │
  │SELECT @ret;                                                            │
  └────────────────────────────────────┘
────────────────────────────────────────
分類:MSSQL
MSSQL/UPDATE文でRANK()を使う
2019年05月22日
[群]ごとの連番を[枝番]として振りたい場合に、
UPDATE文に直接RANK()を使うとエラーとなる。
┌──────────────────────────────────────┐
│UPDATE [表]                                                                 │
│    SET [枝番] = (RANK() OVER(PARTITION BY [群]                             │
│                              ORDER BY [連番] ASC));                        │
├──────────────────────────────────────┤
│ウィンドウ関数は、SELECT 句または ORDER BY 句だけで使用できます。           │
└──────────────────────────────────────┘

これを克服する方法。
┌──────────────────────────────────────┐
│UPDATE [表]                                                                 │
│    SET [枝番] = [入力D].[枝番]                                            │
│    FROM [表] AS [出力D]                                                   │
│        INNER JOIN (                                                        │
│            SELECT [群],                                                    │
│                   [連番],                                                  │
│                   RANK() OVER(PARTITION BY [群]                            │
│                               ORDER BY [連番] ASC) AS [枝番]               │
│                FROM [表]                                                   │
│        ) AS [入力D]                                                       │
│          ON  [入力D].[群]   = [出力D].[群]                               │
│          AND [入力D].[連番] = [出力D].[連番];                            │
└──────────────────────────────────────┘
一旦副表上で[枝番]を生成しておく。
更新対象の[表]とこの副表は、主キーでJOINしないと
副表の先頭一行目(つまり意図しない入力データ)で更新されてしまうので注意。
分類:MSSQL
Oracle/一つ前のレコード(埋める編)
2019年05月21日
一つ前のレコードを参照するには、LAG()関数を使う。
じゃ、NULLの場合に一つ前の値を補填してみようとする。
┌──────────────────────────────────────┐
│SELECT NVL("列",                                                            │
│           LAG("列") OVER(PARTITION BY "グループ列"                         │
│                          ORDER BY     "ソート列"   ASC)                    │
│       ) AS "列"                                                            │
│    FROM "表";                                                              │
└──────────────────────────────────────┘
でもこれだと、本当に一つ前しか埋めてくれない。
  列        列
  ----      ----
  1     →  1
  NULL      1     ←ここしか効かない
  NULL      NULL  ←ここが効かない
  ----      ----

なんと、これを一発で解決してくれる優れものがある。
「IGNORE NULLS」オプションだ。
以下のように、LAG()関数につけてあげるだけ。
┌──────────────────────────────────────┐
│SELECT NVL("列",                                                            │
│           LAG("列" IGNORE NULLS) OVER(PARTITION BY "グループ列"            │
│                                       ORDER BY     "ソート列"   ASC)       │
│       ) AS "列"                                                            │
│    FROM "表";                                                              │
└──────────────────────────────────────┘
お望み通りの結果になる。
  列        列
  ----      ----
  1     →  1
  NULL      1
  NULL      1
  ----      ----
分類:Oracle
Excel/検索機能(Ctrl+F)
2019年03月25日
Excelの検索機能(Ctrl+F)について、仕様をまとめてみた。
・初期セル(ActiveCell)の次から検索を始める
・途中該当があればそこで止まる
・一周し初期セルに戻ってきて、初期セルが該当すればそこで止まる
  初期セルが該当しなければ、該当なしメッセージを出力する

なお、該当するのが一つだけの場合は、再度検索してもうんともすんとも言わない
→一周して初期セル(該当セル)に戻るだけ
分類:Excel
MSSQL/CTEで主キー条件不要だっけ問題
2019年03月14日
┌──────────────────────────────────────┐
│WITH [表1]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表0]                                                     │
│     ),                                                                     │
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表1]                                                     │
│     ),                                                                     │
│     [表3]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表2]                                                     │
│     )                                                                      │
└──────────────────────────────────────┘
例えば、CTEをつなげていくと、ふと、「主キーの結合条件っていらなかったっけ」って
不安になることがある
CROSS JOINが繰り返される想定外のレコードができてるんではという不安だ
┌──────────────────────────────────────┐
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [表1].[キー],                                               │
│                [表1].[バリュー]                                            │
│             FROM [表1]                                                     │
│                 INNER JOIN [表0]                                           │
│                   ON [表0].[キー] = [表1].[キー]                           │
│     ),                                                                     │
└──────────────────────────────────────┘
とかしなくていいのかなという不安だ

でも、これは不要
だって、展開すると以下のように自分で自分に結合している訳だから
(「[表0].[キー] = [表1].[キー]」は実質「[表0].[キー] = [表0].[キー]」だ)
こんなものは要らないということになる
┌──────────────────────────────────────┐
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [表1].[キー],                                               │
│                [表1].[バリュー]                                            │
│             FROM (                                                         │
│                 SELECT [キー],                                             │
│                        [バリュー]                                          │
│                     FROM [表0]                                             │
│             ) AS [表1]                                                     │
│                 INNER JOIN [表0]                                           │
│                   ON [表0].[キー] = [表1].[キー]                           │
│     ),                                                                     │
└──────────────────────────────────────┘

ま、あっても悪さしないけど(以下実験例([表0]の内容がそのまま返る(増殖しない)))
┌──────────────────────────────────────┐
│WITH [表1]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM (                                                         │
│                 VALUES (1, 'A'),                                           │
│                        (2, 'B'),                                           │
│                        (3, 'C')                                            │
│             ) AS [表0]([キー],[バリュー])                                  │
│     ),                                                                     │
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表1]                                                     │
│     ),                                                                     │
│     [表3]([キー],[バリュー]) AS (                                          │
│         SELECT [表2].[キー],                                               │
│                [表2].[バリュー]                                            │
│             FROM [表2]                                                     │
│                 INNER JOIN [表1]                  --本当は不要             │
│                   ON [表1].[キー] = [表2].[キー]  --本当は不要             │
│     )                                                                      │
│SELECT *                                                                    │
│    FROM [表3];                                                             │
└──────────────────────────────────────┘
逆にいうと、気づかなくて厄介といもいえる
分類:MSSQL
ExcelVBA/連想配列の全クリアとその判定方法
2019年03月08日
┌──────────────────────────────────────┐
│Dim 連想配列 As Object                                                      │
│Set 連想配列 = CreateObject("Scripting.Dictionary")                         │
├──────────────────────────────────────┤
│連想配列.RemoveAll  ' 全クリア                                              │
├──────────────────────────────────────┤
│If 連想配列.Count = 0 Then                                                  │
│    MsgBox "空っぽ"                                                         │
│End If                                                                      │
└──────────────────────────────────────┘
分類:ExcelVBA
前へ 1 … 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 … 156 次へ