にむぞノート

新米プログラマーです。 仕事、 趣味で得た知識を適当に残していきます。

PowerShellでクリップボード履歴管理ツールのランチャーを作ってみた。

クリップボード履歴管理ツールとして人気の御三方を 手軽に切り替えられるスクリプトです。

# Loading Assembly
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$CLCL = "C:\Program Files (x86)\CLCL\CLCL.exe"
$ClipHst = "C:\Users\Ueokaj\Downloads\FreeSoft\ClipboardHistory\ClipboardHistory_x64.exe"
$Clibor = "C:\Users\Ueokaj\Downloads\FreeSoft\clibor\Clibor.exe"



    # Making Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Size = New-Object System.Drawing.Size(350,260)
    $Form.Text = "ClipBoard History Management"
    $Form.StartPosition = "CenterScreen"

    # クリップボード履歴ツールの選択グループ
    $MyGroupBox = New-Object System.Windows.Forms.GroupBox
    $MyGroupBox.Location = New-Object System.Drawing.Point(10,10)
    $MyGroupBox.size = New-Object System.Drawing.Size(310,150)
    $MyGroupBox.text = "クリップボード履歴管理ツールを選択してください。"

    # Making Radio button
    $RadioCLCL = New-Object System.Windows.Forms.RadioButton
    $RadioCLCL.Location = New-Object System.Drawing.Point(20,20)
    $RadioCLCL.size = New-Object System.Drawing.Size(280,30)
    $RadioCLCL.Checked = $True
    $RadioCLCL.Text = "CLCL(ファイル、画像の管理もサポート)"

    $RadioClipHst = New-Object System.Windows.Forms.RadioButton
    $RadioClipHst.Location = New-Object System.Drawing.Point(20,60)
    $RadioClipHst.size = New-Object System.Drawing.Size(280,30)
    $RadioClipHst.Text = "ClipBoard History(ダイレクトペーストが可能)"

    $RadioClibor = New-Object System.Windows.Forms.RadioButton
    $RadioClibor.Location = New-Object System.Drawing.Point(20,100)
    $RadioClibor.size = New-Object System.Drawing.Size(280,30)
    $RadioClibor.Text = "Clibor(FIFOに加えLIFOモードもサポート)"

    # Making OK button
    $OKButton = new-object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Point(85,170)
    $OKButton.Size = New-Object System.Drawing.Size(80,40)
    $OKButton.Text = "OK"
    $OKButton.DialogResult = "OK"

    # Making cancel button
    $CancelButton = new-object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Point(175,170)
    $CancelButton.Size = New-Object System.Drawing.Size(80,40)
    $CancelButton.Text = "キャンセル"
    $CancelButton.DialogResult = "Cancel"

    # final operation
    $MyGroupBox.Controls.AddRange(@($RadioCLCL,$RadioClipHst,$RadioClibor))
    $Form.Controls.AddRange(@($MyGroupBox,$OKButton,$CancelButton))
    $Form.AcceptButton = $OKButton
    $Form.CancelButton = $CancelButton
    $Form.MaximizeBox = $False

$Form.TopMost = $True
$dialogResult = $Form.ShowDialog()

Get-Process | ? {$_.ProcessName -in "CLCL", "ClipboardHistory_x64", "Clibor"} `
            | % {Stop-Process -name $_.ProcessName}

if ($dialogResult -eq "OK"){
    if ($RadioCLCL.Checked){
        Start-Process $CLCL
        $Result = "CLCL"
    } elseif ($RadioClipHst.Checked){
        Start-Process $ClipHst
        $Result = "ClipBoard History"
    } elseif ($RadioClibor.Checked){
        Start-Process $Clibor
        $Result = "Clibor"
    }
}else{
    exit
}

[System.Windows.Forms.MessageBox]::Show($Result + "をアクティブ履歴ツールに適用しました。")

JPQLからSQLに変換するスクリプト

いろいろと途中で申し訳ないんですけど、 PowerShellでJPQLからSQLOracle)への変換スクリプトを書いたので、貼っておきます。 もちろん、ここから改善する予定です。 ちょっと、急ぎなので、色ついてないですがすいません。。。

$ErrorActionPreference = "stop"

function IsPascalCase([string] $ss) { if ($ss -cmatch "^[A-Z][a-z][A-Za-z]+$") { return $true } return $false }

function IsSnakeCase([string] $ss) { if ($ss -cmatch "^[a-z]+.[A-Za-z]+$") { return $true } return $false }

function ReplacePascalWithSnake([string] $pascal) { $camel = $pascal -replace $pascal.Substring(0,1), $pascal.Substring(0,1).ToLower() $snake foreach ($i in $camel.ToCharArray()) { $ss = $i.ToString() if ($ss -cmatch "^[A-Z]$") { $snake = $snake + "_" + $ss.ToLower() } else { $snake = $snake + $ss } } return $snake }

function ReplaceCamelWithSnake([string] $camel) { $snake foreach ($i in $camel.ToCharArray()) { $ss = $i.ToString() if ($ss -cmatch "^[A-Z]$") { $snake = $snake + "_" + $ss.ToLower() } else { $snake = $snake + $ss } } return $snake }

$jpql = "SELECT jt JpqlTest jt FROM jt.jpqlId = :jpqlId AND jt.removedFlag = :notRemoved" $tokens = $jpql.Split(" ")

$sql = "" for ($i = 0; $i -lt $tokens.Length; $i++) { # for converting table name. if (IsPascalCase($tokens[$i])) { $sql = $sql + (ReplacePascalWithSnake($tokens[$i])) + " " # for converting field name. } elseif (IsSnakeCase($tokens[$i])) { $sql = $sql + (ReplaceCamelWithSnake($tokens[$i])) + " " } else { $sql = $sql + $tokens[$i] + " " } Write-Host $sql }

$result = $sql.Replace(" "," ") Write-Host $result Set-Clipboard $result

ログに出力されるSQL文にバインド変数を入れ込むバッチ処理

仕事先で製品のテストをする際、
「あれ、DBから結果が得られない?」てなった時は、
ログに出力されるSQL文をDBのコマンド実行で動かして
どの部分でダメになっているのかを特定しています。

ただ、プログラム上で実行されるSQL文とバインド変数が
別々になって出力されるので、いちいち置き換えていくのが面倒です。

↓例えば、こんな感じに。。。 (ログでは、SQL文は1行で出力されますが、見やすさを考慮して改行しています。)

SELECT * 
FROM sample_table AS t0
 WHERE user_id IN (?, ?, ?, ?, ?, ?, ?)
 AND checked_flag = ?

BIND: [101, 102, 103, 104, 105, 106, 107, 0]

これを、コマンド実行できる状態にしようと思ったら、
1、SQL文を全選択し、? を '?' に置換する。
2、1番目の ? を 101 に書き換える。
3、2番目の ? を 102 に書き換える。
(8番目の ? まで書き換えを繰り返す。)

となり、けっこう時間が取られます。
それに、バインド変数が多ければ多いほどかなり時間が取られてしまいます。

よって、バッチ処理を作成して、自動化しようと思ったのが今回の本題です。
私はよくWindows上で自動化する際はバッチファイルを使っていたのですが、
今回の場合、処理する値に右括弧があり、
for文やif文で括弧を使用した際、変数の値に右括弧がある時点で
制御文が終了されてしまう不具合に悩まされそうだったので、
VBScriptを作成することにしました。

以下、ソースコードです。

Option Explicit

Dim query, bind, prompt, title, ins, delims

title = "AutoCreateQuery"
ins = "?"
delims = ","

'ユーザーからSQL文とバインド変数の情報を取得
prompt = "SQL文を入力してください。" & VbCrLf _
        & "バインド変数の挿入先は """ & ins & """ となります。"
query = InputBox(prompt, title)
ExecQuit(query)

prompt = "バインド変数を入力してください" & VbCrLf _
        & "区切り文字は """ & delims & """ です。"
bind = InputBox(prompt, title)
ExecQuit(bind)

bind = bind & ""

'SQL文とバインド変数を各デリミタごとに配列化
Dim aryQuery, aryBind
aryQuery = Split(query, ins)
aryBind = Split(bind, delims)

'SQL文にバインド変数を挿入する
Dim concQuery
Dim i
For i = 0 To UBound(aryBind) Step 1
    concQuery = concQuery + aryQuery(i) + "'" + Trim(aryBind(i)) + "'"
Next
concQuery = concQuery + aryQuery(UBound(aryQuery))

'クリップボードにコピーし、結果を出力する
SetClipBrd(concQuery)

MsgBox "クリップボードに以下のテキストをコピーしました。" & VbCrLf _
        & VbCrLf _
        & concQuery , _
        vbOKOnly , _
        title

'Windowsコマンドでクリップボードに保管
Public Sub SetClipBrd(ByVal str)
    Dim cmd
    cmd = "cmd /c echo " & str & "| clip"
    CreateObject("WScript.Shell").Run cmd, 0
End Sub

'OK以外のボタン操作の場合、処理を終了する
Public Sub ExecQuit(ByVal str)
    If IsEmpty(str) Then
        WScript.Quit
    ElseIf str = "" Then
        MsgBox "何も入力されていません。", vbOKOnly, title
        WScript.Quit
    End If
End Sub

VBScriptはバッチファイルの後継として導入されたスクリプト言語ですが、
Windows10からのブラウザ、EdgeやIE11からはサポート対象外とされており、
段々と使用できる環境がなくなってきそうなツールです。
ですが、こういった分岐処理が多いバッチ処理やダイアログボックスを出したいといった場合は、
まだまだ便利に使えるかもしれませんね。

paiza.io上でJavaを実行した時の改行コード

プログラミングしていて、
ちょっとあのメソッド使ったらどういう結果になったっけ?て
たまに、動作確認したいときがあります。
もちろん、普段の仕事場や自宅の場合は実行環境があるので、
すぐに確認すればいいじゃんていう話なんですが、
これが、ちょっと場所を変えただけで、
「環境がないから無理!」ていう話になるんですよね。

ところが、最近は「paiza.io」というサービスがあり、
ブラウザで手軽にコーディングができるようになりました。
しかも24言語も対応している。(2015年8月現在)

https://paiza.io/

頻繁に使用するわけではないですが、
たまに必要な時があるので、けっこう気に入ってます。
ユーザー登録しなくても実行できるので、
会社のPCで勝手にそういうサイトにログインしてはいけないところだと、
非常にありがたいですよね。

この「paiza.io」ですが、サーバー上で動作するため、
自分のパソコンがWindowsでもLinux上で動くようになるみたいです。

私は主にJavaで使用するので、関係ないといえば、関係ないんですが、
ファイルやパスの区切り文字が違ってくるので、
ある程度、注意していこうと思ってます。

ちなみに改行コードも違うそうで、
Windows上で実行するときは「\r\n」に対し、
paiza.io」ではLinuxなので「\n」になるそうです。
(別にWindowsで「\n」と書いてもこちらのサイトで書く程度のプログラムなら支障ないと思うのですが...)

でも、実際に調べようとして

System.out.println(System.getProperty("line.separator"));

と記述しても正味一行改行された結果しかコンソールに表示されないので、
何が改行コードになっているのかわからん!

なので、ちゃんと調べてみました。

「プログラム」

public class SystemPropertyList {
    public static void main(String[] args) {
        String br;
        switch(System.getProperty("line.separator")) {
            case "\r\n":                // Windows
                br = "\\r\\n"; break;
            case "\n":                  // MacOS X以降、Linux,BSD等
                br = "\\n"; break;
            case "\r":                  // MacOS 9以前
                br = "\\r"; break;
            default:
                br = "不明";
        }
        System.out.println("[改行コード] " + br);
    }
}

「出力結果」

[改行コード] \n


予想通り、「\n」が改行コードになるみたいですね。
あまり、役立つ情報ではないと思いますけど、、、。