【bat】バッチファイルのテンプレート

バッチファイルのテンプレートとして、以下を設定する。
日付時刻の設定
バッチファイル実行場所の利用
バッチファイルと同名ファイルの利用

@echo off

REM 日付時刻の設定
set CURRENT_DATE_TIME_HOUR=%time:~0,2%
set CURRENT_DATE_TIME_MINUTE=%time:~3,2%
set CURRENT_DATE_TIME_SECOND=%time:~6,2%
set CURRENT_DATE_TIME=%date:~0,4%%date:~5,2%%date:~8,2%%CURRENT_DATE_TIME_HOUR: =0%%CURRENT_DATE_TIME_MINUTE: =0%%CURRENT_DATE_TIME_SECOND: =0%

REM バッチファイル実行場所の利用
REM バッチファイルと同名ファイルの利用
set LOG_FILE=%dp0/%n0_%CURRENT_DATE_TIME%.log

【Java】BATからJava呼び出し

BATファイルからJava処理を呼び出します。

@echo off
REM 空欄を指定した場合、後続処理でバッチ実行ディレクトリになる
set USR_EXEDIR=C:\work\bin

echo START Java呼び出し

if "%USR_EXEDIR%" EQU "" (set USR_EXEDIR=%~dp0)
cd /d %USR_EXEDIR%
if %errorlevel% == 1 goto label_cderror

set LIB_DIR=C:\work\lib
set EXE_PATH=.\sub.jar;..\db\ojdbc7.jar;%LIB_DIR%test.jar
set CONF_DIR=..\conf
set CLASS_PATH=.

set JAVA_OPTION=-Xms128M -Xmx128M -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=64M
java %JAVA_OPTION% -classpath %EXE_PATH%;%CONF_DIR%;%CLASS_PATH%;jp.co.test.TestMain > nul

echo END Java呼び出し(0)
exit %errorlevel%

:label_cderror
echo END Java呼び出し(9)
exit(9)

【Excel】選択範囲の取消線削除

選択範囲の取消線を削除します。
納品時の作業で利用することあり。

Sub StrikethroughDel()
    For Each myCell In Selection
        textBefore = myCell.Value
        textAfter = ""
        For i = 1 To Len(textBefore)
            If myCell.Characters(Start:=i, Length:=1).Font.Strikethrough = False Then
                textAfter = textAfter & Mid(textBefore, i, 1)
            End If
        Next i
    Next myCell
End Sub

【Excel】画像自動貼り付け

フォルダ内のJPGファイルをフォルダごとのシートを作成し、
そのシート内に自動で貼り付けします。

Sub JpgPut()

' JpgPut
' JPGファイルを貼り付ける。
' エビデンスが存在する1階層上のフォルダを指定する。(末尾\)
' フォルダ内のJPGファイルは100枚まで。
' 例)
' C:\work\ebi\を指定した場合、
' C:\work\ebi\imgフォルダ内のJPGファイルを貼り付ける。

    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    Application.DisplayStatusBar = True
    Application.StatusBar = "処理中・・・"
    
    Dim count As Integer
    count = 0
    Dim folderPath As String ' 環境によって変更すること。
    folderPath = Worksheets(1).Cells(2, 1).Value
    
    Dim fileName As String
    fileName = Dir(folderPath & "\", vbDirectory)
    
    Dim n As Integer
    n = 0
    
    Dim fileNames(100) As String
    Do While fileName <> ""
        fileNames(n) = fileName
        n = n + 1
        fileName = Dir()
    Loop
    
    Dim i As Integer
    Dim j As Integer
    For j = 0 To n
        fileName = fileNames(j)
        If GetAttr(folderPath & "\" & fileName) And vbDirectory Then
            If fileName <> "." And fileName <> ".." And fileName <> "" Then
                i = 0
                Dim newSheet As Worksheet
                Set newSheet = Worksheets.Add()
                newSheet.Move after:=Worksheets(Worksheets.count)
                newSheet.Name = fileName
                
                Dim jpgPath As String
                jpgPath = Dir(folderPath & "\" & fileName & "\" & "*.JPG", vbNormal)
                Do While jpgPath <> ""
                
                    ' 画像の高さに合わせて「45」の数値を変更すること。
                    newSheet.Cells(i * 45 + 1, 1).Value = jpgPath
                    newSheet.Cells(i * 45 + 2, 2).Select
                    
                    ' Excel2010の場合はここから
                    ' 画像を1*1ポイントで貼り付け
                    Set myShape = Worksheets(fileName).Shapes.AddPicture( _
                    fileName:=folderPath & "\" & fileName & "\" & jpgPath, _
                    linkToFile:=False, _
                    saveWithdocument:=True, _
                    Left:=Selection.Left, _
                    Top:=Selection.Top, _
                    Width:=msoTrue, _
                    Height:=msoTrue)
                    ' 画像を元のサイズに変換(Heightの設定は不要かも)
                    ' Withを利用しないとオブジェクトエラーになる。
                    With myShape
                        LockAspecRatio = msoTrue
                        Hieght = 560
                    End With
                    'myShape.LockAspecRatio = msoTrue
                    'myShape.Hieght = 560
                    ' Excel2010の場合はここまで
                    
                    ' Excel2013の場合はここから
                    'Worksheets(fileName).Picutures.Insert fileName:=folderPath & "\" & fileName & "\" & jpgPath
                    ' Excel2013の場合はここまで
                    
                    i = i + 1
                    count = count + 1
                    jpgPath = Dir()
                Loop
                
            End If
        End If
    Next j
    
    Application.StatusBar = count & "個貼り付け完了"
    Application.ScreenUpdating = True
    Application.EnableEvents = True
End Sub

【Java】フォルダ解凍処理

フォルダ内のファイルを解凍します。

/** 
 * ファイル解凍処理
 */
private void deCompressFile() throws Exception {

  // 圧縮ストリームを宣言する。
  ZipInputStream zis = null;

  try {
    // 作業フォルダのファイルを解凍する。
    zis = ZipInputStream(
      new BufferedInputStream(
        new FileInputStream(this.currentZipFileName)));

    // ファイルのエントリを宣言する。
    ZipEntry entry;
    // ファイルに含まれるエントリ分繰り返す。
    while ((entry = zis.getNextEntry()) != null) {
        // 解凍対象ファイル名を取得する。
        String fileName = entry.getName();
        // ディレクトリの場合
        if (entry.isDirectory()) {
            // ディレクトリを作成する。
            Path filePath = Paths.get(this.currentTmpDir + Const.FILE_PATH_SEPARATOR + fileName);
            Files.createDirectories(filePath);
        // ファイルの場合
        } else {
            // 解凍処理を行う。
            extract(zis, fileName);
        }
    }
  } catch (Exception e) {
    LOGGER.error("エラー発生");
    throw new Exception("エラー発生", e);

  } finally {
    if (zis != null) {
      try {
        zis.close();
      } catch (Exception e) {
        LOGGER.error("エラー発生");
        throw new Exception("エラー発生", e);
      }
    }
  }
}

 * 解凍処理
 * @param zis 圧縮ストリーム
 * @param fileName 解凍対象ファイル名
 */
private void extract(ZipInputStream zis, String fileName) throws Exception {

  // 出力用のストリームを宣言する。
  BufferedOutputStream bos = null;

  try {
    // 解凍対象ファイルのフルパスを取得する。
    Path filePath = Paths.get(this.currentTmpDir + Const.FILE_PATH_SEPARATOR + fileName);

    // 解凍対象ファイルを読み込む。
    int readSize = 0;
    byte[] buffer = new byte[1024];
    bos = new BufferedOutputStream(
        new FileOutputStream(filePath.toString()), 1024);

    // 解凍対象ファイルをファイルとして出力する。
    while ((readSize = zis.read(buffer, 0, buffer.length)) != -1) {
        bos.write(buffer, 0, readSize);
    }
    bos.flush();

  } finally {
    if (bos != null) {
      bos.close();
    }
    zis.closeEntry();
  }
}

【Java】フォルダ圧縮処理

フォルダ内のファイルを圧縮します。

/** 
 * フォルダ圧縮処理
 * @param 圧縮対象フォルダ「C:\work\dir」
 * @param 圧縮ファイル名「C:\work\send_20181104150000.zip」
 */
private void dirCompress(String dir, String zipFileName) throws Exception {

  // 圧縮ストリームオブジェクトを宣言する。
  ZipOutputStream zos = null;

  try {
    // 圧縮ストリームオブジェクトを生成する。
    zos = ZipOutputStream(
      new FileOutputStream(
        new File(zipFileName)), Charset.forName("MS932"));

    // フォルダ内のファイル一覧を取得する。
    List<Path> filePahtList = Files.list(Paths.get(dir).collect(Collectors.toList());

    // ファイル一覧分繰り返す。
    for (Path filePath : filePathList) {
      archive(zos, filePath, Paths.get(dir).getFileName().toString() + "\\" + filePath.getFileName().toString());
    }

    zos.closeEntry();
    zos.finish();

  } catch (Exception e) {
    LOGGER.error("エラー発生");
    throw new Exception("エラー発生", e);

  } finally {
    if (zos != null) {
      try {
        zos.close();
      } catch (Exception e) {
        LOGGER.error("エラー発生");
        throw new Exception("エラー発生", e);
      }
    }
  }
}

 * 圧縮処理
 * @param zos 圧縮ストリーム
 * @param filePath 圧縮対象ファイルパス
 * @param fileName 圧縮対象ファイル名
 */
private void archive(ZipOutputStream zos, Path filePath, String fileName) throws Exception {

  // 圧縮対象ファイルの読込ストリームを宣言する。
  BufferedInputStream bis = null;

  try {
    // zipエントリを作成する。
    zos.putNextEntry(new ZipEntry(fileName));

    // ファイルの場合
    if (! Files.isDirectory(filePath)) {
      // 圧縮対象ファイルを読み込む。
      bis = new BufferedInputStream(new FileInputStream(filePath.toString()));

      // 圧縮対象ファイルをzipファイルに出力する。
      int readSize = 0;
      byte[] buffer = new byte[1024];
      while ((readSize = bis.read(buffer, 0, buffer.length)) != -1) {
        zos.write(buffer, 0, readSize);
      }
    }
  } finally {
    if (bis != null) {
      bis.close();
    }
    zos.closeEntry();
  }
}

【Java】画像のマスク処理

画像に対して個人情報等をマスクする際に利用します。

private void imageMaskBlack(String imageFile) thorws Exception {

  // 変数を宣言する。
  BufferedImage bimg = null;
  Graphics graphics = null;
  ImageReader jpgReader = null;
  ImageWriter jpgWriter = null;

  try {
    // イメージファイルを読み込む。(ImageIO.readは利用しない方針)
    jpgReader ImageIO.getImageReadersByFormatName("jpeg").next();
    jpgReader.setInput(ImageIO.createImageInputStream(new File(imageFile)));
    bimg = jpgReader.read(0);

    // Graphicsオブジェクトを取得する。
    graphics = bimg.getGraphics();
    graphics.setColor(Color.BLACK);
    // X座標、Y座標、幅、高さを指定し黒色でマスクする。
    // 画像の左上がX座標:0、Y座標:0
    graphics.fillRect(100, 50, 100, 100);
    graphics.drawImage(bimg, 0, 0, null);

    // 品質と解像度指定
    // イメージを書き込むため、ImageIOからjpg用のImageWriterを取得する。
    jpgWriter = ImageIO.getImageWritersByFormatName("jpeg").next();

    // ImageWriterのパラメータ設定
    // パラメータを取得する。
    JPEGImageWriteParam jpgWriteParam = (JPEGImageWriteParam)jpgWriter.getDefaultWriteParam();
    // パラメータに品質指定を行うモードを指定する。
    jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    // パラメータに品質を指定する。(0.0f~1.0f)
    jpgWriteParam.setCompressionQuality(0.5f);

    // ImageWriterのメタデータの設定
    // メタデータを取得する。
    IIOMetadata imageMeta = jpgWriter.getDefaultImageMetadata(new ImageTypeSpecifier(bimg), jpgWriteParam);
    // メタデータからXMLのツリー構造を取得する。
    Element tree = (Element)imageMeta.getAsTree("javax_imageio_jpeg_image_1.0");
    // ツリー構造から要素「JFIF」を取得する。
    Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);
    //DPI指定を行うモードを指定する。
    jfif.setAttribute("resUnits", "1");
    // X座標は300dpiを指定する。
    jfif.setAttribute("Xdensity", 300);
    // Y座標は300dpiを指定する。
    jfif.setAttribute("Ydensity", 300);
    // メタデータにツリー構造を設定し直す。
    imageMeta.setFromTree("javax_imageio_jpeg_image_1,0", tree);

    // これまでに行った設定を元にイメージファイルを出力する。(ImageIO.writeは利用しない方針)
    jpgWriter.setOutput(ImageIO.createImageOutputStream(new File(imageFile)));
    jpgWriter.write(null, new IIOImage(bimg, null, imageMeta), jpgWriteParam);

  } finally {
    if (grahics != null) {
      graphics.dispose();
      graphics = null;
    }
    if (jpgWriter != null) {
      jpgWriter.reset();
      jpgWriter = null;
    }
    if (jpgReader != null) {
      jpgReader.reset();
      jpgReader = null;
    }
    if (bimg != null) {
      bimg.flush();
      bimg = null;
    }
  }
}

【Java】ビルドを自動で行う

build.xmlをantでビルドする作業を自動で行います。

  • 起動バッチ

    @echo off
    set ANT_HOME=D:/Product/apache-ant-1.10.1
    set BUILD_FILE=build.xml
    set TARGET=destcopy
    set PROJECT_HOME=D:/Product/APP/
    cd %PROJECT_HOME%
    if %ERRORLEVEL%==0 (
      echo ビルドを開始します。
      echo ログは%PROJECT_HOME%/build.logに出力しています。
      call %ANT_HOME%/bin/ant -f %BUILD_FILE% -l build.log %TARGET%
    )
    if %ERRORLEVEL%==0 (
      echo ビルドを終了します。
    ) else (
      echo エラーが発生しています。ログを確認してください。
    )
    pause
    
  • build.xml

    <?xml version"1.0" encoding="UTF-8"?>
    <project name="APP-TEST" basedir="." default="destcopy">
    
      <!-- classpath指定 -->
      <path id="classpath">
        <fileset dir="./lib">
          <include name="*.jar" />
        </fileset>
        <fileset dir="./WebContent/WEB-INF/lib">
          <include name="*.jar" />
        </fileset>
    
      <!-- 初期化 -->
      <target name="clean" description="コンパイル済のclassファイルとjarファイルを削除">
        <delete dir="./dest" />
        <delete dir="./bin" />
      </target>
    
      <!-- プロジェクトコンパイル -->
      <target name="compile" depends="clean" description="コンパイル開始">
        <mkdir dir="./bin" />
        <javac debug="on" fork="true" destdir="./bin" srcdir="./src" classpathref="classpath" deprecation="on" encoding="UTF-8" includeantruntime="flase">
          <compilerarg value="-Xlint:unchecked" />
        </javac>
      </target>
    
      <!-- jarファイル作成 -->
      <target name="destcopy" depends="compile" description="jarファイル作成開始">
        <mkdir dir="./dest" />
        <copy toDir="./dest/standalone/deployments/APP-TEST.war">
          <fileset dir="./WebContent" />
        </copy>
        <copy toDir="./dest/standalone/configuration">
          <fileset dir="./jbossconfiguration" />
        </copy>
        <copy toDir="./dest/standalone/deployments/APP-TEST.war/WEB-INF/classes">
          <fileset dir="./bin/" />
        </copy>
        <touch file="./dest/standalone/deployments/APP-TEST.war.dodeploy" />
      </target>
    </project>
    

【bat】バッチファイルで全てのCSVファイル内の特定文字列を編集する

バッチファイルで同階層にあるCSVファイル内のの特定文字列を編集します。

前提条件
編集前のCSVファイル:TEST_yyyyMMddhhmmss.csv
編集後のCSVファイル:after_TEST_yyyyMMddhhmmss.csv
特定文字列:電話番号と仮定し、3桁、4桁、4桁のハイフン区切りに編集
補足:フォーマットは以下の例の通り
      電話番号は空欄の可能性あり
      電話番号の後続列は空欄の可能性あり
例
編集前
1,山田太郎,202-0003,09011112222,男
2,山田次郎,202-0003,,男
3,山田太郎,202-0003,,

編集後
1,山田太郎,202-0003,090-1111-2222,男
2,山田次郎,202-0003,,男
3,山田太郎,202-0003,,
@echo off
setlocal ENABLEDELAYEDEXPANSION
cd %~dp0
set LOG_FILE=%~n0.log
echo [ INFO ] %date% %time% CSVファイルの編集を開始します。 >>%LOG_FILE%

for %%x in (TEST_*.csv) do (
  echo %%x
  set OUTPUT_FILE=after_%%x
  type nul > !OUTPUT_FILE!

  for /f "tokens=1-5 delims=," %%a in (%%x) do (
    set STRTMP=%%d
    if not "!STRTMP!" == "" (
      if "!STRTMP:~0, 3!" == "090" (
        set STRTMP=!STRTMP:~0, 3!-!STRTMP:~4, 4!-!STRTMP:~7, 4!
        echo %%a,%%b,%%c,!STRTMP!,%%e >>!OUTPUT_FILE!
      ) else (
        echo %%a,%%b,%%c,,%%d >>!OUTPUT_FILE!
      )
    ) else (
      echo %%a,%%b,%%c,%%d,%%e >>!OUTPUT_FILE!
    )
  )
)
echo [ INFO ] %date% %time% CSVファイルの編集を終了します。 >>%LOG_FILE%
endlocal
exit /b
ポイント
・delimsでカンマ区切りを指定する。
・tokensで区切った配列のどのインデックスを利用するか決定する。
  配列は%%a~%%eで参照可能。
・値が空欄の場合、配列が詰められる。(ココがややこしい)
  1列目:配列の長さは5
  2列目:配列の長さは4
  3列目:配列の長さは3
・「type nul > !OUTPUT_FILE!」を行うことで、1度初期化してから実行している。
・繰り返し処理中は「setlocal ENABLEDELAYEDEXPANSION」~「endlocal」内で
  変数は「!XXX!」で参照可能。

【Oracle】バッチファイルからSQLPlusを起動しデータ取得

バッチファイルからSQLPlusを起動しデータ取得を行います。
主にエビデンス取得で利用します。
テスト対象の実施前後で取得し、結果ファイルを比較します。

  • 起動バッチ

    @echo off
    set DATE_TIME=%date:~0, 4%%date:~5, 2%%date:~2, 2%%time:~0, 2%%time:~3, 2%%time:~6, 2%
    
    set IP_ADDRESS=192.168.XX.XX
    set PORT_NO=1521
    set SID=XXX
    set USER_ID=XXX
    set PASSWORD=XXX
    set SQL_FILE=outputCsvAllData.sql
    set SPOOL_FILE=select_AllData.csv
    
    rem -s サイレントモード
    rem    プロンプトやログインメッセージを表示しなくなる。
    rem -L 1度だけログイン
    rem    ログインに失敗すると3回まで再試行するが、1回で終了する。
    sqlplus -s -L %USER_ID%/%PASSWORD%@%IP_ADDRESS%:%PORT_NO%/%SID% @%SQL_FILE%
    
    move %SPOOL_FILE% %DATE_TIME%_%SPOOL_FILE%
    
    echo %DATE_TIME%_%SPOOL_FILE%を出力しました。
    pause
    
  • SQLファイル(outputCsvAllData.sql)

    set echo off
    set linesize 9999
    set pagesize 0
    set trimspool on
    set feedback off
    
    spool select_AllData.csv
    @@select_AllData.sql
    spool off
    
  • 「@@」はパス名を含まないファイル名の場合、「呼び出し元のスクリプトのパス」を補完する。

    例)
    以下のフォルダ構成の場合、
    「@@」をつけると呼び出せるが、「@」の場合、エラーとなる。
    ・C:/起動バッチ
    ・C:/test/outputCsvAllData.sql
    ・C:/test/select_AllData.sql
    
  • SQLファイル(select_AllData.sql)

    prompt テーブル名
    SELECT 項目1 || 't' || 項目2 || 't' || 項目3 FROM テーブル名;
    
  • 文字列結合している理由は「【Oracle】SQLPlusで空白除去」を参照。