Excelのアドインを作成しました

10月 10th, 2014 by onoue Leave a reply »


Excel / Jon Juan

システムのバージョンアップに伴ない、アプリケーションのテストを実施する事になりました。

この作業は動作確認をしつつ、ひたすら画面のキャプチャーを取得してExcelに貼りつけるという単純な作業になります。とはいえ、完全に自動化して実施できるほど簡単でもなく、何度もやる必要のない仕事です。

そこで、すこしでも楽をしようとExcelのアドインを使って、キャプチャーした複数の画像ファイルをエクセルに一括で貼りつけるアドインを使用しました。 アドインを使うと、提出用のExcelブックをマクロで汚すことなく、マクロと同じように作業を自動化できます。

もっともアドインを作って登録するまでが、かなり煩雑な手順が必要なのですが…。

ポイントとしては最近のExcelだと画像を挿入すると、画像そのものが貼られるのではなく、画像のリンクが貼られてしまうので、そのままでは提出用としては使いずらいものとなります。そこで一度貼りつけた画像をクリップボードにコピーして、再度同じ場所にペーストする事で、画像がリンクになる事を回避しています。(Excel上では後からではリンクを内部画像に変換できないようです)

元ネタはどこかの掲示板で取得したマクロです。先人の努力に感謝です。 以下にそのソースを掲載します。

Sub 複数の画像を挿入()
'
' 複数の画像を挿入 Macro
'
' Keyboard Shortcut:
'
    Dim strFilter As String
    Dim Filenames As Variant
    Dim PIC       As Picture
    
     ' 「ファイルを開く」ダイアログでファイル名を取得
     strFilter = "画像ファイル(*.jpg;*.jpeg;*.gif;*.bmp;*.png),*.jpg;*.jpeg;*.gif;*.bmp;*.png"
    Filenames = Application.GetOpenFilename( _
                    FileFilter:=strFilter, _
                    Title:="図の挿入(複数選択可)", _
                    MultiSelect:=True)
    If Not IsArray(Filenames) Then Exit Sub
  
     ' ファイル名をソート
    Call BubbleSort_Str(Filenames, True, vbTextCompare)
    
     ' 貼り付け開始セルを選択
     'Range("C5").Select
    
     ' マクロ実行中の画面描写を停止
     Application.ScreenUpdating = False
    ' 順番に画像を挿入
     For i = LBound(Filenames) To UBound(Filenames)
        Set PIC = ActiveSheet.Pictures.Insert(Filenames(i))
      
         '-------------------------------------------------------------
        ' 画像の各種プロパティ変更
         '-------------------------------------------------------------
        With PIC
            .Top = ActiveCell.Top        ' 位置:アクティブセルの上側に重ねる
            .Left = ActiveCell.Left      ' 位置:アクティブセルの左側に重ねる
            .Placement = xlMove          ' 移動するがサイズ変更しない
            .PrintObject = True          ' 印刷する
        End With
        With PIC.ShapeRange
            .LockAspectRatio = msoTrue   ' 縦横比維持
            ' 画像の高さをアクティブセルにあわせる
            ' 結合セルの場合でも対応
            ' .Height = ActiveCell.MergeArea.Height
            .ScaleHeight 0.5, msoTrue
            .ZOrder msoSendToBack
        End With
        ActiveCell.Select
        'Set ActiveCell.Width = PIC.ShapeRange.Width
        Dim row, col As Integer
        row = ActiveCell.row
        col = ActiveCell.Column
        ActiveCell.ColumnWidth = PIC.ShapeRange.Width / 6
        PIC.CopyPicture
        PIC.Delete
        ActiveSheet.Paste
        
        Dim count As Integer
        count = ActiveSheet.Shapes.count
        ActiveSheet.Shapes(count - 1).ZOrder msoSendToBack

        ' 次の貼り付け先を選択(アクティブセルにする)[例:5個下のセル]
        'ActiveCell.Offset(5).Select
        ActiveCell.Offset(0, 2).Select
    
         Set PIC = Nothing
    Next i
  
     ' 終了
     Application.ScreenUpdating = True
    MsgBox i - 1 & "枚の画像を挿入しました", vbInformation

 End Sub

 ' バブルソート(文字列)
Private Sub BubbleSort_Str( _
    ByRef Source As Variant, _
    Optional ByVal SortAsc As Boolean = True, _
    Optional ByVal Compare As VbCompareMethod = vbTextCompare)
  
     If Not IsArray(Source) Then Exit Sub
  
     Dim i As Long, j As Long
    Dim vntTmp As Variant
    For i = LBound(Source) To UBound(Source) - 1
        For j = LBound(Source) To LBound(Source) + UBound(Source) - i - 1
            If StrComp(Source(IIf(SortAsc, j, j + 1)), _
                       Source(IIf(SortAsc, j + 1, j)), Compare) = 1 Then
                vntTmp = Source(j)
                Source(j) = Source(j + 1)
                Source(j + 1) = vntTmp
            End If
        Next j
    Next i

 End Sub


' ある一つのサブフォルダについての処理
Private Function importImagesFromOneSubDir(sub_dir, y, root_dir)
    'MsgBox sub_dir.Name
    
    ' このフォルダ内の画像をすべて列挙
    file_name = Dir(sub_dir & "\*.*")
    Do While file_name <> ""
        ' このファイルの拡張子を調べる
        If isImageFile(file_name) Then
            ' 画像であれば,取り込んで次の行へ
            importImageFile file_name, y, root_dir, sub_dir
            y = y + 1
        End If
        
        ' 次のファイルを取得
        file_name = Dir()
    Loop
        
    ' 現在の行を返す
    importImagesFromOneSubDir = y
    
End Function
        

' 画像ファイルかどうか,拡張子で判定する
Private Function isImageFile(file_name)
    
    ' ピリオドは後ろから何文字目か
    pos_period = InStrRev(file_name, ".")
    If pos_period > 0 Then
        ' 拡張子を切り出し
        file_ext = LCase(Mid(file_name, pos_period + 1))
        
        ' 画像の拡張子か?(小文字で指定可)
        If _
            file_ext = "jpg" Or _
            file_ext = "jpeg" Or _
            file_ext = "bmp" Or _
            file_ext = "gif" Or _
            file_ext = "png" _
        Then
            ' 画像であると判定
            ret = True
        Else
            ret = False
        End If
    Else
        ret = False
    End If
    ' http://officetanaka.net/excel/vba/tips/tips57.htm
    
    isImageFile = ret
End Function


' ある一つの画像ファイルをシート中に取り込む
Private Sub importImageFile(file_name, y, root_dir, sub_dir)
    file_path = sub_dir & "\" & file_name
    
    ' 一列目にはサブフォルダ名を
    ActiveSheet.Cells(y, 1).Value = sub_dir.Name
    
    ' 二列目には画像を
    ActiveSheet.Cells(y, 2).Select
    Set myShape = ActiveSheet.Shapes.AddPicture( _
          fileName:=file_path, _
          LinkToFile:=False, _
          SaveWithDocument:=True, _
          Left:=Selection.Left, _
          Top:=Selection.Top, _
          Width:=Application.CentimetersToPoints(6), _
          Height:=Application.CentimetersToPoints(1))
        ' http://www.moug.net/tech/exvba/0120020.html
        ' http://www.moug.net/tech/exvba/0070012.html
    
    ' この行高を自動調整
    Cells(y, 1).RowHeight = Application.CentimetersToPoints(1)

End Sub

 Sub picIns(ByVal r As Range, _
           ByVal s As String, _
           ByVal W As Single, _
           ByVal H As Single)

    With ActiveSheet.Pictures.Insert(s).ShapeRange
        If (W > 0) And (H > 0) Then
            .LockAspectRatio = msoFalse
            .Width = W
            .Height = H
        ElseIf W > 0 Then
            .Width = W
        ElseIf H > 0 Then
            .Height = H
        End If
        .Left = r.Left
        .Top = r.Top
    End With
 End Sub
Advertisement

Comments are closed.

%d人のブロガーが「いいね」をつけました。