【Excel】ライブラリ参照

Excelでオブジェクトを変数宣言するには
遅延バインディングと事前バインディングの2種類の方法がある。

実装の違い(例として、FileSystemObjectを利用)

  • 遅延バインディング
  • Dim objFSO As Object
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
  • 事前バインディング
  • 「ツール」→「参照設定」で
    「Microsoft Scripting Runtime」にチェックを付ける。

    Dim objFSO As New FileSystemObject
    または、
    Dim objFSO As FileSystemObject
    Set objFSO = New FileSystemObject
    

一言で言えば、変数宣言の型が
遅延バインディングはObject型
事前バインディングは特定のオブジェクト型
となっている。

  • 遅延バインディング(実行時バインディング)
  • オブジェクトが Object 型として宣言された変数に代入する場合、
    遅延(実行時)にバインディングされる。
    この型のオブジェクトは、任意のオブジェクトへの参照を保持できるが、
    事前バインディングされたオブジェクトの利点をほとんど持たない。

  • 事前バインディング
  • 特定のオブジェクト型として宣言された変数に代入する場合、
    オブジェクトは事前(コンパイル時に)バインディングされる。
    事前バインディングされたオブジェクトでは、アプリケーションが実行される前に、
    コンパイラによってメモリの割り当てとその他の最適化が実行される。
    また、自動クイックヒントが表示されるようになる。

    【Excel】名前の定義削除

    名前の定義は有能だと思うのですが、
    参考ブックからコピーすると一緒にコピーされ、
    収集つかなくなるためこれで削除します。

    Option Explicit
    
    Private Sub NameDefDel()
        Dim Ans, RefStyle, n
        
        Ans = MsgBox("実行しますか?", vbYesNo, "実行確認")
        If Ans = vbNo Then Exit Sub
        
        RefStyle = Application.ReferenceStyle
        
        If RefStyle = xlR1C1 Then
            Application.ReferenceStyle = xlA1
        Else
            Application.ReferenceStyle = xlR1C1
        End If
    
        For Each n In ActiveWorkbook.Names
            If Not n.Name Like "*!Print_Area" And _
                Not n.Name Like "*!Print_Titles" Then
                n.Delete
            End If
        Next
    
        Application.ReferenceStyle = RefStyle
        
        MsgBox "完了しました!"
    End Sub
    

    【Java】例外内容を文字列で取得する

    例外内容を文字列で取得します。
    例外内容をメール本文等に出力する際に利用します。

    /** 
     * 例外内容取得処理
     * @param 例外オブジェクト
     * @return 例外内容文字列
     */
    public static String getTrace(Throwable th) {
    
        StringBuilder sb = new StringBuilder();
        String lineSeparator = System.getProperty("line.separator");
    
        if (th != null) {
            sb.append(th.getClass().getName() + ":" + th.getMessage());
            StackTraceElement[] stack = th.getStackTrace();
            if (stack != null) {
                for (int i = 0; i < stack.length; i++) {
                    sb.append(lineSeparator);
                    sb.append("\tat " + stack[i].toString());
                }
            }
            sb.append(lineSeparator);
    
            Throwable causeTh = th.getCause();
            String caused = getCaused(causeTh);
            sb.append(caused);
        }
    
        return sb.toString();
    }
    
    /** 
     * 例外内容取得処理(原因)
     * @param 例外オブジェクト
     * @return 例外内容文字列
     */
    public static String getCaused(Throwable th) {
    
        StringBuilder sb = new StringBuilder();
        String lineSeparator = System.getProperty("line.separator");
        Throwable chainTh = null;
    
        if (th != null) {
            sb.append("Caused by: " + th.getClass().getName() + ":" + th.getMessage());
            StackTraceElement[] stack = th.getStackTrace();
            if (stack != null) {
                for (int i = 0; i < stack.length; i++) {
                    sb.append(lineSeparator);
                    sb.append("\tat " + stack[i].toString());
                }
            }
            sb.append(lineSeparator);
    
            chainTh = th.getCause();
    
        } else {
            return sb.toString();
        }
    
        return sb.append(getCaused(chainTh)).toString();
    }
    
    /**
     * テストドライバ
     * @param args
     */
    public static void main(String[] args) {
    
        try {
            test();
        } catch (Throwable th) {
            System.out.println("JavaAPIで例外出力");
            th.printStackTrace();
    
            System.out.println();
            System.out.println("独自APIで例外出力");
            System.out.println(getTrace(th));
        }
    }
    public static void test() throws Exception {
        try {
            try {
                int i = 0;
                int j = 100;
                int k = j/i; // ここでエラー発生
            } catch (Exception e) {
                throw new Exception("エラー", e);
            }
        } catch (Exception e) {
            //throw e;
            throw new Exception("エラー2", e);
        }
    }
    

    【VisualStudio】他フォームが呼べない場合の対処

    外部からインポートしたプロジェクトで
    他フォームをShowやShowDialogで開く際、
    FileNotFoundが発生している場合、プロジェクトフォルダ内の「App.config」を見直す。

    外部ライブラリ等を参照している場合、パスが記載されていることがあり、
    そのパスに外部ライブラリがないことで発生している。

    【bat】UTF-8のDBデータ取得

    バッチファイルでUTF-8のDBデータを取得します。
    DBデータ取得部分はDBに併せて変更する。

    @echo off
    REM バッチ実行ファイルと同階層に実行したいSQLファイルを配置する。
    REM SQLファイルは1文を1行で記載する。
    REM SQLファイルは「PARAM1」と「PARAM2」を置換文字列としておく。
    setlocal ENABLEDELAYEDEXPANSION
    
    REM SQLファイルの置換内容の入力
    set /P START_DAY="開始日(YYYYMMDD)を入力してください。:"
    set /P END_DAY="終了日(YYYYMMDD)を入力してください。:"
    
    REM バッチ実行ディレクトリの設定
    set CURRENT_DIR=%~dp0
    
    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 DB接続ファイルのディレクトリに移動
    REM 今回の例ではMySQLとする
    set MYSQL_DIR="C:\Program Files\MySQL\MySQL Server 5.7\bin"
    cd /d %MYSQL_DIR%
    
    set SQL_FILE=%CURRENT_DIR%%~n0.sql
    set SQL_FILE_TMP=%CURRENT_DIR%%~n0_tmp.sql
    set WORK_DIR="D:\work"
    set OUT_DIR=%CURRENT_DIR%output\%CURRENT_DATE_TIME%
    mkdir %OUT_DIR%
    
    set ROWNUM=1
    
    REM コンソールの文字コードをUTF-8に変更
    chcp 65001
    
    for /f "tokens=*" %%i in (%SQL_FILE%) do (
    set SQL_LINE1=%%i
    set SQL_LINE2=!SQL_LINE1:PARAM1=%START_DAY%!
    set SQL_LINE3=!SQL_LINE2:PARAM2=%END_DAY%!
    echo !SQL_LINE3! > %SQL_FILE_TMP%
    
    REM DB接続と実行
    REM 今回の例ではMySQLとする
    mysql -h localhost -u ユーザID -pパスワード -P ポート番号 docrdb < "%SQL_FILE_TMP%" >> %WORK_DIR%\!ROWNUM!.txt
    
    set /A ROWNUM=!ROWNUM!+1
    )
    
    del %SQL_FILE_TMP%
    
    REM コンソールの文字コードをShift-JISに変更
    chcp 932
    
    REM DBデータ出力結果のファイル名を変更
    move %WORK_DIR%\1.txt %OUT_DIR%\01_案件数.txt
    move %WORK_DIR%\2.txt %OUT_DIR%\02_案件数不備あり.txt
    move %WORK_DIR%\3.txt %OUT_DIR%\03_案件数不備なし.txt
    

    【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