ちょっと作ってみたツール

SEを10年くらいやっていました。あったら便利だなーってツールを書いています

whichをWindowsでやってみる

使い方

  1. ソースを適当なファイル名で保存する(例: which.bat)(できれば、PATHが通った所がいいです)
  2. コマンドプロンプトでwhich (プログラム名)
    (例: which notepad)

ソース

@ECHO OFF
CALL :CHECK %1
FOR /D %%e IN ('echo %PATHEXT%') DO (
    FOR /F "delims=" %%n IN ('echo %1%%e') DO (
        CALL :CHECK %%n
    )
)
@ECHO ON
@GOTO :EOF

:CHECK
IF NOT "%~f$PATH:1" == "" (
    ECHO %~f$PATH:1
)
EXIT /B

which for windows

バッチとWSHを同居する方法

いままでバッチとWSHを同居させるときは

REM = 1 /*
バッチ
*/
WSH

としてきたのだけど、REM = 1が表示されるのがすごく嫌だったのだけど、バッチを公開されている先駆者である「主に言語とシステム開発に関して」さんのソースを見ていたら、@if (0) == (0)という書き方を見てびっくりした。 なるほど、そういう書き方があるのか(JScript の基本条件コンパイル条件コンパイル変数)。

language-and-engineering.hatenablog.jp

フォルダ配下のwordファイルをpdf化する

使い方

  1. 下のソースを適当な名前で保存する(ここではexportpdf.js)
  2. コマンドプロンプトから下記のように実行
cscript exportpdf.js (wordが格納されているフォルダ) (PDFを出力するフォルダ)

ソース

var prop = {
    'ExportFormat': 17,       // 出力するファイルのフォーマット PDF:17, XPS:18
    'OpenAfterExport':false, // 変換後、変換されたファイルを開くかどうか
    'OptimizeFor':1,         // 印刷用に最適化(0)にするか、画面用に最適化(1)するか
    'Range':0,               // エクスポートする範囲を全体(0)にするか選択したページ(1)か、
                                 // 現在のページ(2)か、FromとToで指定するか(3)
    'From': 1,               // Rangeで3を指定したときの開始ページ
    'To':   2,               // Rangeで3を指定したときの終了ページ
    'Item': 0,               // エクスポート時テキストのみ(0)を含めるか、テキストをマークアップ付き(7)で含めるかを指定する 
    'IncludeDocProps': false,// 新しいファイルに文書のプロパティを含めるかどうか
    'KeepIRM':false,         // ソース文書が IRM によって保護されている場合に、IRM アクセス許可を XPS 文書にコピーする場合は true。
    'CreateBookmarks':2,     // ブックマークを出力しないか(0)、見出しのみ(1)か、ヘッダやフッタなども含むか(2)
    'DocStructureTags':false,// コンテンツのフローや論理構成など) を含める場合は true
    'BitmapMissingFonts':false, // テキストのビットマップを含める場合は true。テキスト フォントを参照する場合は false。
    'UseISO19005_1': true,      // PDF の使用を ISO 19005-1 として標準化されている PDF のサブセットに限定する場合は true
    'ShowRevisionsAndComments': false, // 書内の変更履歴およびコメントを表示(true)、非表示(false)
    'RevisionsView': 0          // 表示する画面を最終版(0)にするか、初版(1)にするか 
};

if ( WScript.arguments.length != 2 ) {
    WScript.Echo("arguments: InputFolder, OutputFolder");
    WScript.Quit();
}

var fso = new ActiveXObject("Scripting.FileSystemObject");
var word = new ActiveXObject("Word.Application");
var inputBase  = fso.GetAbsolutePathName(WScript.arguments.Item(0));
var outputBase = fso.GetAbsolutePathName(WScript.arguments.Item(1));

var inputReg = new RegExp("^" + inputBase);

makeWalker(getChildren, func)(inputBase);

function fileFunc(file) {
    var output = file.replace(inputBase, outputBase);
    
    if (fso.GetExtensionName(file).match(/(doc|docx)$/i)) {
        var doc = null;
        output = output.replace(/(doc|docx)$/i, "pdf");
        try {
            doc = word.Documents.Open(file);
            doc.Windows.Item(1).View.RevisionsView = prop['RevisionsView'];
            //doc.Windows.Item(1).View.ShowRevisionsAndComments  = prop['ShowRevisionsAndComments '];
            
            doc.ExportAsFixedFormat (
                output, prop['ExportFormat'],
                prop['OpenAfterExport'], prop['OptimizeFor'],
                prop['Range'], prop['From'], prop['To'],
                prop['Item'],  prop['IncludeDocProps'], 
                prop['KeepIRM'], prop['CreateBookmarks'],
                prop['DocStructureTags'], prop['BitmapMissingFonts'],
                prop['UseISO19005_1']
            );
            
        } finally {
            if (doc) { doc.Close() }
        }
    }
}

function folderFunc(folder) {   
    var output = folder.replace(inputBase, outputBase);
    if (!fso.FolderExists(output)) {
        fso.CreateFolder(output);
    }
}

function func(node) {
    if (fso.FolderExists(node)) {
        folderFunc(node);
    } else if (fso.FileExists(node)) {
        fileFunc(node);
    }
}

function getChildren(node) {
    var children = [];
    if (fso.FolderExists(node)) {
        for (var e = new Enumerator(fso.GetFolder(node).SubFolders); !e.atEnd(); e.moveNext()) {
            children.push(e.item().Path);
        }
        for (var e = new Enumerator(fso.GetFolder(node).Files); !e.atEnd(); e.moveNext()) {
            children.push(e.item().Path);
        }
    }
    return children;
}

function makeWalker(getChildren, func) {
    return function walk(node) {
        func(node);
        var children = getChildren(node);
        for ( var i = 0; i < children.length; i++) {
            walk(children[i]);
        }
    }
}

PrintScreenする度にExcelに張り付けるスクリプト

使い方

  1. 下のソースを適当なvbsにコピーする
  2. Excelを開き、適当な名前で保存する。このときファイルは閉じない。
  3. 1.で作ったvbsを次のコマンドで実行 cscript (1.で作ったvbs)
  4. PrintScreenを押すと、Excelの下に画像が張り付けられます
  5. 使い終わったら3.をCtrl+Cで終了させてください

ソース

span = 2 
col = 2

Set excel = GetObject(, "Excel.Application")   

row = getRow

WScript.Echo(row)


While True
  For Each fmt In excel.ClipboardFormats
    If fmt = 9 Then
      row = getRow
      excel.ActiveSheet.Cells(row + span, col).Select
      excel.ActiveSheet.Paste
      excel.ExecuteExcel4Macro "CALL(""User32"", ""OpenClipboard"", ""JJ"", 0)"
      excel.ExecuteExcel4Macro "CALL(""User32"", ""EmptyClipboard"", ""J"")"
      excel.ExecuteExcel4Macro "CALL(""User32"", ""CloseClipboard"", ""J"")"
    End If
  Next  
  WScript.Sleep 500
Wend

Function getRow()
  bottom = excel.ActiveSheet.UsedRange.Top + excel.ActiveSheet.UsedRange.Height
  For Each shape In excel.ActiveSheet.Shapes
    If shape.Top + shape.Height > bottom Then
      bottom = shape.Top + shape.Height
    End If
  Next

  row = 1
  While excel.ActiveSheet.Cells(row, 1).Top < bottom
    row = row + 1
  Wend
  getRow = row
End Function

when screen shot, paste it to active excel

Excelの線を直線にする

Excelを使っていると線を引きたいんだけど、直線をひけなかったりするので、困ってしまいました。

使い方

  1. 下のソースを.vbsで保存
  2. 直線にしたい線をクリック
  3. 1.で保存したvbsをダブルクリック

ソース

上の点を基準にそろえる

Set excel = GetObject(, "Excel.Application")

Set shape = excel.Selection.ShapeRange(1)

If shape.HorizontalFlip = 0 And shape.VerticalFlip = 0 Then
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = 0  Then
  shape.Left = shape.Left + shape.Width
ElseIf shape.HorizontalFlip =  0 And shape.VerticalFlip = -1 Then
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = -1 Then
  shape.Left = shape.Left + shape.Width
End If

shape.Width = 0

excel line align based with top

左の点を基準にそろえる

Set excel = GetObject(, "Excel.Application")

Set shape = excel.Selection.ShapeRange(1)

If shape.HorizontalFlip = 0 And shape.VerticalFlip = 0 Then
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = 0  Then
  shape.Top = shape.Top + shape.Height
ElseIf shape.HorizontalFlip =  0 And shape.VerticalFlip = -1 Then
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = -1 Then
  shape.Top = shape.Top + shape.Height
End If

shape.Height = 0

excel line align based with left

右で揃える

Set excel = GetObject(, "Excel.Application")

Set shape = excel.Selection.ShapeRange(1)

If shape.HorizontalFlip = 0 And shape.VerticalFlip = 0 Then
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = 0  Then
  shape.Top = shape.Top + shape.Height
ElseIf shape.HorizontalFlip =  0 And shape.VerticalFlip = -1 Then
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = -1 Then
  shape.Top = shape.Top + shape.Height
End If

shape.Height = 0

excel line align based with right

下を基準に揃える

Set excel = GetObject(, "Excel.Application")

Set shape = excel.Selection.ShapeRange(1)

If shape.HorizontalFlip = 0 And shape.VerticalFlip = 0 Then
  shape.Left = shape.Left + shape.Width
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = 0  Then
ElseIf shape.HorizontalFlip =  0 And shape.VerticalFlip = -1 Then
  shape.Left = shape.Left + shape.Width
ElseIf shape.HorizontalFlip = -1 And shape.VerticalFlip = -1 Then
End If

shape.Width = 0

excel line align based with bottom

正規表現でファイル検索をする

Windowsにはfindコマンドはないですし、grepコマンドもありませんので、こんな感じで。

使い方

greplike.bat 検索文字列(正規表現) [対象ディレクトリ]

サンプル

greplike.bat echo C:\Windows\System32\drivers\etc

greplike.bat test

ソース

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
IF "%2" == "" (SET PWD="%CD%") ELSE (SET PWD=%~2)
for /F "delims=" %%f in ('dir /A-D /S /B "%PWD%"') do (
  FINDSTR "%~1" "%%~f" > NUL
  IF "!ERRORLEVEL!" == "0" ECHO %%f
)
ENDLOCAL
@ECHO ON

gistbc8dc3ae84ceb7568806bf913f4a48b8

行数カウント

行数をカウントします

使い方

wc-l .bat (対象ファイル)

サンプル

wc-l.bat C:\Windows\System32\drivers\etc\services

ソース

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET COUNT=0
FOR /F %%f IN (%1) DO (
    SET /A COUNT=!COUNT! + 1
)
echo !COUNT!
ENDLOCAL
@ECHO ON

gistb7ac778003b944882b043ee13a86864e