美文网首页
VBA 查找Excel的文字包括查找图形里的文字

VBA 查找Excel的文字包括查找图形里的文字

作者: 马云生 | 来源:发表于2023-12-28 10:01 被阅读0次

Option Explicit

Private Const CONFIG_COL As Long = 2            ' 設定列

Private Const CONFIG_START_ROW As Long = 2      ' 設定開始行

Private Const DATA_START_ROW As Long = 12       ' 出力開始行

' ####################################################

' 描画制限プロパティ

' ####################################################

Property Let Focus(ByVal Flag As Boolean)

With Application

.EnableEvents = Not Flag

.ScreenUpdating = Not Flag

.Calculation = IIf(Flag, xlCalculationManual, xlCalculationAutomatic)

End With

End Property

' ====================================================

' GREP実行

' ====================================================

Public Sub GrepBooks()

Dim shtMain As Worksheet        ' ワークシート

Dim strPath As String           ' フォルダパス

Dim strPassword As String       ' パスワード

Dim strSheetName As String      ' 検索対象シート名

Dim strDsShtName As String      ' 検索除外シート名

Dim strWords As String          ' 検索文字列

Dim intExtCol As Integer        ' 参考情報出力列

Dim fso As Object               ' ファイルシステムオブジェクト

Dim fl As Variant               ' ファイルオブジェクト

Dim intTargetCnt As Integer     ' 対象ファイル数

Dim intProcCnt As Integer       ' 処理件数

Dim lngIdx As Long

Dim colGrep As Collection       ' GREP結果格納用コレクション

Dim dicGrep As Object           ' GREP結果ディクショナリ

Dim varGrep As Variant          ' コレクション取出し用オブジェクト(ディクショナリ)

Dim firstRow

Dim lastRow

Dim countIndex

Set shtMain = ActiveSheet

' フォルダ存在チェック

strPath = shtMain.Cells(CONFIG_START_ROW, CONFIG_COL).Text

If Dir(strPath, vbDirectory) = "" Then

MsgBox "指定のフォルダ「" & strPath & "」は存在しません。", vbExclamation

Exit Sub

End If

' 確認ダイアログ

If MsgBox("指定したフォルダ以下にあるxlsxファイルをGREPします。" & vbCrLf & "よろしいですか?", vbQuestion + vbYesNo) = vbNo Then

Exit Sub

End If

' 設定値取得

strPassword = shtMain.Cells(CONFIG_START_ROW + 1, CONFIG_COL).Text

strSheetName = shtMain.Cells(CONFIG_START_ROW + 2, CONFIG_COL).Text

strDsShtName = shtMain.Cells(CONFIG_START_ROW + 3, CONFIG_COL).Text

strWords = shtMain.Cells(CONFIG_START_ROW + 4, CONFIG_COL).Text

intExtCol = Val(shtMain.Cells(CONFIG_START_ROW + 5, CONFIG_COL).Text)

lngIdx = 0

intTargetCnt = 0

intProcCnt = 0

' 描画制限

Focus = True

firstRow = DATA_START_ROW

lastRow = shtMain.UsedRange.Rows.Count

For countIndex = lastRow To firstRow Step -1

Rows(countIndex).Delete

Next

'Set clearRng = shtMain.Range("A12:F" & (shtMain.UsedRange.Rows.Count - 12))

'For Each clearRow In clearRng.Rows

' clearRow.ClearContents

'Next clearRow

' 対象ファイル数取得

Set fso = CreateObject("Scripting.FileSystemObject")

For Each fl In fso.GetFolder(strPath).Files

If UCase(fso.GetExtensionName(fl.Path)) = "XLSX" Or UCase(fso.GetExtensionName(fl.Path)) = "XLS" Or UCase(fso.GetExtensionName(fl.Path)) = "XLSM" Then

intTargetCnt = intTargetCnt + 1

End If

Next

' ファイルごとに処理

For Each fl In fso.GetFolder(strPath).Files

If UCase(fso.GetExtensionName(fl.Path)) = "XLSX" Or UCase(fso.GetExtensionName(fl.Path)) = "XLS" Or UCase(fso.GetExtensionName(fl.Path)) = "XLSM" Then

' ステータスバー更新

Focus = False

intProcCnt = intProcCnt + 1

Application.StatusBar = "GREP処理中... (" & CStr(intProcCnt) & "/" & CStr(intTargetCnt) & " ファイル)"

Application.DisplayAlerts = True

Focus = True

' 各ブックを検索

Set colGrep = SearchBook(fl.Path, strPassword, strSheetName, strDsShtName, strWords, intExtCol)

' 結果出力

For Each varGrep In colGrep

shtMain.Cells(DATA_START_ROW + lngIdx, 1).Value = CStr(lngIdx + 1)

shtMain.Cells(DATA_START_ROW + lngIdx, 2).Value = fl.Name

shtMain.Cells(DATA_START_ROW + lngIdx, 3).Value = varGrep("Sheet")

shtMain.Cells(DATA_START_ROW + lngIdx, 4).Value = varGrep("Row")

shtMain.Cells(DATA_START_ROW + lngIdx, 5).Value = varGrep("Text")

ActiveSheet.Cells(DATA_START_ROW + lngIdx, 6).Value = varGrep("ExtText")

lngIdx = lngIdx + 1

Next

End If

Next

Focus = False

' ステータスバークリア

Application.StatusBar = False

MsgBox "GREP完了" & vbCrLf & CStr(intTargetCnt) & "ファイル中一致した箇所:" & CStr(lngIdx), vbInformation

End Sub

' -----------------------------------------------

' 個別ファイル検索

' -----------------------------------------------

Private Function SearchBook(pFilePath As String, pPassword As String, pSheet As String, pDsSht As String, pWords As String, pExtCol As Integer) As Collection

Dim wb As Workbook              ' ワークブック

Dim ws As Variant               ' ワークシート

Dim rng As Range                ' 検索一致セル

Dim adr As String               ' 最初に見つかったセルのAddress

Dim dicGrep As Object           ' GREP結果ディクショナリ

Dim colGrep As New Collection   ' GREP結果格納用コレクション

Dim strDsShts() As String       ' 検索除外シート名をSplitした配列

Dim dicDsSht As Object

Dim strWords() As String        ' 検索文字列をSplitした配列

Dim i As Integer

' ワークブックを開く

If pPassword <> "" Then

Set wb = Workbooks.Open(Filename:=pFilePath, Password:=pPassword, ReadOnly:=True, UpdateLinks:=0)

Else

Set wb = Workbooks.Open(Filename:=pFilePath, ReadOnly:=True, UpdateLinks:=0)

End If

ActiveWindow.Visible = False

' 検索除外シート名

strDsShts = Split(pDsSht, ",")

Set dicDsSht = CreateObject("Scripting.Dictionary")

For i = 0 To UBound(strDsShts)

dicDsSht.Add strDsShts(i), 1

Next i

' 検索文字列Split

strWords = Split(pWords, ",")

' ワークシートでループ

For Each ws In wb.Worksheets

' シート名が一致する場合のみ

If InStr(ws.Name, pSheet) <> 0 And Not dicDsSht.Exists(ws.Name) And ws.Visible Then

' 検索文字列ごとにループ

For i = 0 To UBound(strWords)

' 検索(初回)

Set rng = ws.Cells.Find(strWords(i))

' 検索にヒットした場合のみ処理

If Not rng Is Nothing Then

' 最初に見つかったセルのAddfressを保持(終了判定用)

adr = rng.Address

' 表示行の場合のみ処理

If Not rng.EntireRow.Hidden Then

Set dicGrep = CreateObject("Scripting.Dictionary")

dicGrep.Add "Sheet", ws.Name

dicGrep.Add "Row", rng.Row

dicGrep.Add "Text", rng.Text

If pExtCol > 0 Then dicGrep.Add "ExtText", ws.Cells(rng.Row, pExtCol).Text

' コレクションに追加

colGrep.Add dicGrep

End If

' 検索(2件目以降)

Do

Set rng = ws.Cells.FindNext(After:=rng)

If rng Is Nothing Then Exit Do

If rng.Address = adr Then Exit Do

' 表示行の場合のみ処理

If Not rng.EntireRow.Hidden Then

Set dicGrep = CreateObject("Scripting.Dictionary")

dicGrep.Add "Sheet", ws.Name

dicGrep.Add "Row", rng.Row

dicGrep.Add "Text", rng.Text

If pExtCol > 0 Then dicGrep.Add "ExtText", ws.Cells(rng.Row, pExtCol).Text

' コレクションに追加

colGrep.Add dicGrep

End If

Loop

End If

Dim shp As Shape

For Each shp In ws.Shapes

Dim strText As String

Dim rowLIndex, colLIndex, rowRIndex, colRIndex

Dim pos As Integer

On Error Resume Next

strText = shp.TextFrame.Characters.Text

pos = InStr(strText, strWords(i))

If strText <> "" And pos > 0 Then

Set dicGrep = CreateObject("Scripting.Dictionary")

dicGrep.Add "Sheet", ws.Name

dicGrep.Add "Row", shp.TopLeftCell.Row

dicGrep.Add "Text", strText

rowLIndex = shp.TopLeftCell.Row

colLIndex = shp.TopLeftCell.Column

rowRIndex = shp.BottomRightCell.Row

colRIndex = shp.BottomRightCell.Column

dicGrep.Add "ExtText", "図形位置:[" & rowLIndex & "行:" & colLIndex & "列]、[" & rowRIndex & "行:" & colRIndex & "列]"

' コレクションに追加

colGrep.Add dicGrep

End If

Next shp

Next i

End If

Next

' ワークブッククローズ

wb.Close SaveChanges:=False

Set SearchBook = colGrep

End Function

相关文章

网友评论

      本文标题:VBA 查找Excel的文字包括查找图形里的文字

      本文链接:https://www.haomeiwen.com/subject/aobdndtx.html