Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
14 / 14 / 7
Регистрация: 21.06.2013
Сообщений: 163
Записей в блоге: 1
1

Поиск документов с макросами на жестком диске компьютера

25.09.2014, 09:52. Показов 1984. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Уважаемые профи VBA!
Подскажите пожалуйста, каким образом можно осуществить поиск на жестком диске документов содержащих макросы?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.09.2014, 09:52
Ответы с готовыми решениями:

Найти на жестком диске компьютера все файлы с заданным именем
Ввести с клавиатуры произвольное имя текстового файла. - Найти на жестком диске компьютера все...

Найти на жестком диске компьютера все файлы с заданным именем
Работа с текстовыми файлами. Поиск файлов. Для всех вариантов: - Ввести с клавиатуры...

Найти на жестком диске компьютера все файлы с заданным именем
Буду рад любой помощи :) - Ввести с клавиатуры произвольное имя текстового файла. - Найти на...

Найти на жестком диске компьютера все файлы с заданным именем, произвести их обработку
- Ввести с клавиатуры произвольное имя текстового файла. - Найти на жестком диске компьютера все...

8
Заблокирован
25.09.2014, 10:03 2
Имеется ввиду только WORD или глобально (в т.ч. EXCEL, COREL, AUTOCAD, SOLIDWORKS etc...)
1
14 / 14 / 7
Регистрация: 21.06.2013
Сообщений: 163
Записей в блоге: 1
25.09.2014, 10:44  [ТС] 3
Если есть разница, то достаточно только Excel
0
Заблокирован
25.09.2014, 11:38 4
...
Цитата Сообщение от anvg
... использовать библиотеку Microsoft Visual Basic for Applications Extensibility
Цитата Сообщение от Казанский
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Function DeleteAllVBA() As Boolean 
'удаляет все компоненты VBA в текущей книге и возвращает True, если они были 
Dim i&, j& 
With ActiveWorkbook.VBProject 
For i = .VBComponents.Count To 1 Step -1 
If .VBComponents(i).Type = 100 Then 'vbext_ComponentType.vbext_ct_Document, т.е. модуль книги, листа 
With .VBComponents(i).CodeModule 
j = .CountOfLines - .CountOfDeclarationLines 
If j Then .DeleteLines 1, .CountOfLines: DeleteAllVBA = True 
End With 
Else 'остальные типы: модуль, модуль класса, форма 
.VBComponents.Remove .VBComponents(i): DeleteAllVBA = True 
End If 
Next 
End With 
End Function 
 
Sub test() 
Const FLDR = "c:\temp\1\" 
Dim w, q 
If MsgBox("Внимание!!!" & vbLf & _ 
"Будут удалены ВСЕ компоненты VBA (макросы, формы, пользовательские функции) из ВСЕХ файлов Excel в папке " _ 
& FLDR & vbLf & "Продолжить?", vbCritical + vbYesNoCancel + vbDefaultButton2) <> vbYes Then Exit Sub 
Application.EnableEvents = False 'для запрещения макросов Workbook_Open в открываемых книгах 
w = Dir(FLDR & "*.xls") 'фактически *.xls* 
Do While w <> "" 
With Workbooks.Open(FLDR & w) 
.Close DeleteAllVBA 'если компонентов VBA не было, закрыть без сохранения 
End With 
w = Dir 
Loop 
Application.EnableEvents = True 
End Sub
Цитата Сообщение от anvg
Рекурсивное сканирование подпапок для поиска файлов Excel можно сделать и в таком варианте (необходимо подключить библиотеку Microsoft Shell Controls And Automation).
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Private Const filterOnlyFolders = 32 
Private Const filterOnlyFiles = 64 
Private FShell As Shell32.Shell 
Private FRow As Long 
Private FSheet As Worksheet 
 
Public Sub StartScan() 
Set FSheet = ThisWorkbook.Worksheets(1) 
Set FShell = New Shell32.Shell 
FRow = 0 
Scan "d:\Temp" 
End Sub 
 
Public Sub Scan(ByVal folderPath As String) 
Dim pFolder As Shell32.Folder3 
Dim pItems As Shell32.FolderItems3 
Dim pItem As Shell32.FolderItem 
 
Set pFolder = FShell.Namespace(folderPath) 
Set pItems = pFolder.Items 
pItems.Filter filterOnlyFiles, "*.xls;*.xlsm;*.xlsb" 
If pItems.Count > 0 Then 
For Each pItem In pItems 
FRow = FRow + 1 
'соответственно вместо записи пути и имени файла можно вызвать 
'функцию удаления DeleteAllVBA от Казанского 
FSheet.Cells(FRow, 1).Value = pItem.Path 
Next pItem 
End If 
Set pItems = pFolder.Items 
pItems.Filter filterOnlyFolders, "*.*" 
If pItems.Count > 0 Then 
For Each pItem In pItems 
Scan pItem.Path 
Next pItem 
End If 
End Sub
3
2785 / 717 / 106
Регистрация: 04.02.2011
Сообщений: 1,443
25.09.2014, 12:30 5
Лучший ответ Сообщение было отмечено GreyW как решение

Решение

Рекурсивный обход папок без подключения внешних библиотек с регулируемой глубиной вложенности папок:
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Option Explicit
 
 
' Выбор папки для обработки через диалог
Sub FindMacro()
    Dim fd As FileDialog, vrtSelectedItem As Variant, sFolder As String
    
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)
    
    fd.AllowMultiSelect = False
    fd.InitialFileName = ThisWorkbook.Path & "\"
    
    If fd.Show = -1 Then
        Application.ScreenUpdating = False
        For Each vrtSelectedItem In fd.SelectedItems
            sFolder = vrtSelectedItem
            If Right(sFolder, 1) <> "\" Then sFolder = sFolder & "\"
            ' на всю глубину -1; текущ. папка 0, уроверь вложения >=1
            Call RecureiveSearch(sFolder, -1)
        Next vrtSelectedItem
        Application.ScreenUpdating = True
    End If
End Sub
 
 
' Рекурсия по папкам с управляемой глубиной обхода
Private Sub RecureiveSearch(MyPath As String, ByVal Level As Long)
    Dim MyName As String, PS As String, DirList() As String
    Dim i As Long, n As Long
    
    PS = Application.PathSeparator
    ReDim DirList(0 To 0) As String
    
    MyName = Dir(MyPath, vbDirectory)
    Do While MyName <> ""
        If MyName <> "." And MyName <> ".." Then
            n = GetAttr(MyPath & MyName)
            If (n And vbDirectory) = vbDirectory Then
                ReDim Preserve DirList(0 To UBound(DirList) + 1) As String
                DirList(UBound(DirList)) = MyPath & MyName & PS
            Else
                If MyName Like "*.xls*" And Not MyName Like ThisWorkbook.Name Then
                    Call CheckMacro(MyPath, MyName)
                End If
            End If
        End If
        MyName = Dir
    Loop
    If Level = 0 Then Exit Sub
    If Level > 0 Then Level = Level - 1
    If UBound(DirList) > 0 Then
        For i = 1 To UBound(DirList)
            Call RecureiveSearch(DirList(i), Level)
        Next i
    End If
End Sub
 
 
Private Sub CheckMacro(MyPath As String, MyName As String)
    Dim wbk As Workbook, vbc As Object, s As String, b As Boolean
    
    Set wbk = Workbooks.Open(MyPath & MyName, False, True)
    
    b = False
    For Each vbc In wbk.VBProject.VBComponents
        If vbc.CodeModule.CountOfLines > 0 Then
            s = vbc.CodeModule.Lines(1, vbc.CodeModule.CountOfLines)
            s = Replace(s, "Option Explicit", "")
            s = Trim$(Replace(s, vbCrLf, ""))
            If Len(s) > 0 Then
                b = True
                Exit For
            End If
        End If
        s = vbc.CodeModule.Name
    Next
    
    If b Then
        Debug.Print MyPath & MyName
    End If
    
    wbk.Close False
    Set wbk = Nothing
End Sub
1
14 / 14 / 7
Регистрация: 21.06.2013
Сообщений: 163
Записей в блоге: 1
25.09.2014, 16:43  [ТС] 6
Спасибо!
Только в варианте mc-black нужно добавить On Error Resume Next перед строчкой:
Visual Basic
1
    Set wbk = Workbooks.Open(MyPath & MyName, False, True)
Иначе спотыкается на битых файлах.
0
2785 / 717 / 106
Регистрация: 04.02.2011
Сообщений: 1,443
25.09.2014, 16:54 7
Цитата Сообщение от GreyW Посмотреть сообщение
Только в варианте mc-black нужно добавить On Error Resume Next перед строчкой:
Ага, и желательно сразу после
Visual Basic
1
2
3
Set wbk = Workbooks.Open(MyPath & MyName, False, True)
' указать
On Error Resume 0
Заметил, что 75-я строка листинга поста #5 ничего полезного не делает - можно удалять
1
14 / 14 / 7
Регистрация: 21.06.2013
Сообщений: 163
Записей в блоге: 1
31.10.2014, 12:06  [ТС] 8
mc-black
В вышеуказанной процедуре FindMacro() указана опция fd.AllowMultiSelect = False.
Нужно ли тогда использовать For Each vrtSelectedItem In fd.SelectedItems?
Заранее спасибо.
1
2785 / 717 / 106
Регистрация: 04.02.2011
Сообщений: 1,443
31.10.2014, 15:52 9
Вы правы, это лишнее. Имело бы смысл только с fd.AllowMultiSelect = True. Подгонял имеющийся код под заданную задачу по-быстрому на коленке. Пример рабочий, просто остался избыточный код. С другой стороны, если когда-то надо будет иметь кусок кода для нескольких папок, этот код хватит подправить только в одном месте.
1
31.10.2014, 15:52
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.10.2014, 15:52
Помогаю со студенческими работами здесь

Поиск изображений на жёстком диске
Есть программа для просмотра изображений, но нужно что-бы когда нажимаешь в проводнике на диск...

Поиск файлов на жёстком диске
Как можно реализовать например, при нажатии на кнопку открывается меню выбора диска, после выбора...

Поиск и восстановление данных на жестком диске
Привет! Посоветуйте хорошие программы, можно платные, для поиска и восстановления данных на...

Найти на жестком диске компьютера все файлы с заданным именем, поочередно вывести на экран их содержимое
Привет. Подсобите пожалуйста в решении задачки. Всё уже запускается, ищется, но, даже при...

Полетела ОС на жёстком диске
Друзья! В общем ерунда такая. Полетела ОС на жёстком диске.Вставил его в мультифунциональный...

Пространство на жестком диске
Всем салам! У меня такой вопрос, место которое занимает папка &quot;Пользователи&quot;(в моих документах)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru