ACCESSで自動スクショ

最近、業務自動化を研究していてその過程で
Webのスクショ取る業務があってそれ自動化できないかと
思ってACCESS/VBAでやってみました。
IEしか対応していませんが・・・・・

IEShotという全画面キャプチャ取得できるコードがあり
有効活用させていただきました。ありがとうございます。

下記の構造でテーブルの準備が必要です
seqNo
targetURL
targetSheetName
startCol
endCol
statRow
endRow
targetComent

エラーハンドリングも適当です。ご使用は自己責任で
お願いします。

Option Compare Database
'Sleep関数用
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'Sleep関数用
'キャプチャ用
Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
'画面アクティブ制御
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function ShowWindowAsync Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
'取得対象用構造体
Type RetVal
    SiteUrl As String
    ExcelsheetName As String
    ExcelComent As String
    ExcelStartCol As String
    ExcelEndCol As String
    ExcelStartRow As Long
    ExcelEndRow As Long
End Type

'//*******************************************************************
'//
'// テーブルからURLを取得しIEを開きキャプチャを取得しEXCELに貼付
'//
'//*******************************************************************
Sub AutoCapmain()

    Dim targetObject As RetVal
    Dim objIE As InternetExplorer
    Dim targetCnt As Long
    
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
    
    'テーブルを読込んでURLとEXCELシート名を取得する
    Dim rs As New ADODB.Recordset
    rs.Open "select * from t_TargetCap order by seqNo", CurrentProject.Connection
    targetCnt = DCount("*", "t_TargetCap")

    'EXCEL起動
    Dim xlApp   As Excel.Application
    Dim xlbook As Excel.Workbook
    Dim xlSheet As Excel.Worksheet
    Dim nextxlSheet As Excel.Worksheet
    Set xlApp = CreateObject("Excel.Application")
    xlApp.Visible = True
    Set xlbook = xlApp.Workbooks.Add
    Dim i As Long
    Dim CngSheetName As String
    Dim chckVal As Boolean
    
    Do Until rs.EOF
        targetObject = getTarget(rs)
        Call ieNavi(objIE, targetObject.SiteUrl)
        Call ieCheck(objIE)
        'IEの画面キャプチャ取得
        Call getCapture(objIE)
        i = xlbook.Worksheets.Count
        
        'シート判別
        Set xlSheet = xlbook.Worksheets(i)
        If targetObject.ExcelsheetName <> "" Then
            CngSheetName = targetObject.ExcelsheetName
        Else
            CngSheetName = xlSheet.Name
        End If
        chckVal = searchSheetName(xlbook, targetObject.ExcelsheetName)
        
        If chckVal = True Then
            Set xlSheet = xlbook.Worksheets(CngSheetName)
        '最終レコードでシート名が同一でない場合はシート名変更のみ
        ElseIf i = targetCnt And chckVal = False Then
            xlSheet.Name = CngSheetName
        ElseIf i <> targetCnt And chckVal = False Then
        'シートを追加
            xlSheet.Name = CngSheetName
            Set nextxlSheet = xlbook.Worksheets.Add(after:=xlbook.Worksheets(i))
            Set xlSheet = xlbook.Worksheets(CngSheetName)
            i = i + 1
        Else
            MsgBox ("シート設定関連でエラー発生")
        End If
            
        '画面貼付
        With targetObject
            Call runExcel(xlSheet, .ExcelStartCol, .ExcelEndCol, .ExcelStartRow, .ExcelEndRow, .ExcelComent)
        End With
        rs.MoveNext
        xlApp.CutCopyMode = False
    Loop
    ' 終了処理
    xlbook.Worksheets(1).Activate
    rs.Close
    objIE.Quit
    Set objIE = Nothing

End Sub

'//****************************************************
'//
'//  EXCELの操作(指定シートにEXCEL貼付)
'//
'//****************************************************
Function runExcel(xlSheet As Worksheet, startCol As String, _
                    endCol As String, startRow As Long, endRow As Long, eComment As String)
'On Error GoTo Error_Sub

    Dim resizeRFlg As Long
    Dim resizeCFlg As Long
    resizeRFlg = 1
    resizeCFlg = 1
    
    'EXCELをアクティブにする
    xlSheet.Activate
    
    '列の設定(何も入っていない場合の措置)
    Dim sWidth As Long
    If startCol = "" Then
        startCol = "A"
    End If
    Dim sCol As Variant
    Dim eCol As Variant
    If endCol = "" Then
        endCol = "F"
        resizeCFlg = 0
    End If
    
    '行の設定(何も入っていない場合の措置)
    Dim sHeight As Long
    Dim rows As Long
    If startRow < 1 Then
        startRow = 1
    End If
    If endRow < 1 Then
        endRow = 20
        resizeRFlg = 0
    End If
    If endRow - startRow > 0 Then
        rows = endRow - startRow
    Else
        rows = 50
    End If
    
    '高さ、幅指定
    sWidth = xlSheet.Range(startCol & "1" & ":" & endCol & "1").Width
    sHeight = xlSheet.Range("A" & startRow & ":A" & endRow).height
        
    Dim shapeName As String
    'クリップボードのスクリーンショット貼付
    xlSheet.Paste
    
   'TODO:クリップボードの貼付けが失敗したりするので安定しない
    shapeName = selection.ShapeRange.Name
   
   
   'リサイズが必要な場合
    If resizeCFlg = 1 Or resizeRFlg = 1 Then
        With xlSheet.Shapes(shapeName)
            .LockAspectRatio = msoFalse
            .height = sHeight
            .Width = sWidth
            .Top = xlSheet.Range(startCol & startRow).Top
            .Left = xlSheet.Range(startCol & startRow).Left
        End With
    End If
    
   'コメント記載
    If eComment <> "" Then
        Dim comCol As Variant
        comCol = CNumAlp(xlSheet, endCol) + 1
        comCol = CNumAlp(xlSheet, comCol)
        xlSheet.Range(comCol & startRow).Value = eComment
        xlSheet.Range(comCol & "1").select
    End If
    
    Exit Function
    
'Error_Sub:
'    MsgBox ("EXCELとブラウザを終了させて再度ACCESSを実行してください。" & _
'            "頻発する場合はエラー内容をお伝えください。" & _
'            "エラー番号: " & Err.Number & Chr(13) & Err.Description)
    
End Function
'同一名のシート名称があるか判別
Function searchSheetName(xlsbook As Excel.Workbook, sheetName As String) As Long

    Dim ws As Worksheet
    For Each ws In xlsbook.Sheets
        If ws.Name = sheetName Then
            ' 存在する
            searchSheetName = True
            Exit Function
        End If
    Next
    searchSheetName = False

End Function

'//****************************************************
'//
'//  テーブルから対象のURLとシート名、貼付位置を取得する
'//
'//****************************************************
Function getTarget(rs As ADODB.Recordset) As RetVal
    
    With getTarget
        .SiteUrl = Nz(rs!targetURL)
        .ExcelsheetName = Nz(rs!targetSheetName)
        .ExcelStartCol = Nz(rs!startCol)
        .ExcelEndCol = Nz(rs!endCol)
        .ExcelStartRow = Nz(rs!statRow)
        .ExcelEndRow = Nz(rs!endRow)
        .ExcelComent = Nz(rs!targetComent)
    End With

End Function
'//****************************************************
'//
'//  画面をキャプチャする
'//
'//****************************************************
Sub getCapture(objIE As Object)

    'IEを最前面に表示
    'http://www.macrogirls.net/iesamplecode/vbaie_day2_3.html
    If IsIconic(objIE.hWnd) Then
        ShowWindowAsync objIE.hWnd, &H9
    End If
    SetForegroundWindow (objIE.hWnd)
    
    'IEShotを使用しスクロール対応
    IEShot.IEShot4IE11 objIE, , ""
    
    'Alt+PrintScreen
    'http://www.excel.studio-kazu.jp/kw/20080423200952.html
    'keybd_event &H2C, 1, 0, 0

End Sub
'https://www.vba-ie.net/ie/iefind.html
'指定したURLを表示
Sub ieNavi(objIE As InternetExplorer, _
           urlName As String)
  objIE.navigate urlName
  Call ieCheck(objIE)
End Sub
  '完全にページが表示されるまで待機する
Sub ieCheck(objIE As InternetExplorer)
  Dim timeOut As Date
  timeOut = Now + TimeSerial(0, 0, 20)
  Do While objIE.Busy = True Or objIE.ReadyState <> 4
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
  Loop

  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.Document.ReadyState <> "complete"
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
   Loop
End Sub
'https://ateitexe.com/change-alphabet-integer/
'カラムのアルファベットを数値に変換する関数
Function CNumAlp(xlSheet As Worksheet, va As Variant) As Variant
  Dim al As String
 
  If IsNumeric(va) = True Then '数値だったら
    al = xlSheet.cells(1, va).Address(RowAbsolute:=False, ColumnAbsolute:=False) '$無しでAddress取得
    CNumAlp = Left(al, Len(al) - 1)
  Else 'アルファベットだったら
    CNumAlp = xlSheet.Range(va & "1").Column '列番号を取得
  End If
End Function

最初の1回目でエラー出たりでなかったりするんですが
そこの原因がわからない・・・・。
誰か助けていただけると幸いです。

コメント

このブログの人気の投稿

証券外務員1種勉強(計算式暗記用メモ)

GASでGoogleDriveのサブフォルダとファイル一覧を出力する

マクロ経済学(IS-LM分析)