Страницы: 1
RSS
поиск файлов содержащих макросы
 
Здравствуйте,Уважаемые Специалисты!:)  
Помогите,пожалуйста с такой задачей.  
Для ускорения процесса СВОЕЙ работы в фирме я создавал файлы с элементами VBA  
(то есть - это наличие userform,макросы,функции)  
 
Итоговый файл отчёта ДЛЯ ФИРМЫ должен содержать только данные.  
Некоторый период времени(при доработке кода)мне пришлось сохранять файлы с элементами VBA.  
Но дарить схематику своей работы фирме(всё создавал в свободное время) не намерен.  
 
Подскажите,пожалуйста могу ли я каким-то образом найти эти файлы?  
 
Может быть особый запрос при поиске файлов в проводнике Windows,Total Commander,другой программы мне это сможет подсказать?  
Быть может есть код VBA умеющий определить о наличии макросов,форм в несколько сотен файлов?  
 
Огромное спасибо за ответ:)
 
Если так жалко свой код, то можно использовать библиотеку Microsoft Visual Basic for Applications Extensibility. Используя её, открывая очередной файл для анализа, можно определить наличие в этой книге форм, модулей, а так же кода в них.
 
Спасибо,anvg!:)  
Простите - а можно поподробнее Ваш вариант?:)
 
Например, по наличию классов, модулей, форм в книге такая функция  
Public Function hasMacro(ByVal inBook As Workbook) As Boolean  
   Dim pVBProject As VBIDE.VBProject  
   Dim pVBComponent As VBIDE.VBComponent  
   Set pVBProject = inBook.VBProject  
   If pVBProject.VBComponents.Count > 0 Then  
       For Each pVBComponent In pVBProject.VBComponents  
           Select Case pVBComponent.Type  
           Case vbext_ComponentType.vbext_ct_MSForm  
               hasMacro = True  
           Case vbext_ComponentType.vbext_ct_ClassModule  
               hasMacro = True  
           Case vbext_ComponentType.vbext_ct_StdModule  
               hasMacro = True  
           Case vbext_ComponentType.vbext_ct_Document  
               'анализ кода листов, книги  
           End Select  
       Next pVBComponent  
   Else  
       hasMacro = False  
   End If  
End Function
 
Насколько я понимаю указанную функцию нужно подселить в ту книгу,которую я должен открыть,чтобы проверить наличие классов, модулей, форм.  
Замкнутый круг?
 
Зачем же?  
Создаёте книгу с макросом, который сканирует заданную папку и её подпапки на наличие файлов. Приблизительно, опуская не существенное  
Public sub Scan(ByVal startPath As String)  
Dim pBook As Workbook  
'код сканирования и получения имени файла  
Set pBook = Application.Workbooks.Open("d:\path\bookname.xls")  
If hasMacro(pBook) Then  
ThisWorkbook.Worksheets(1).Cells(i, 1).Value = pBook.FullName  
End If  
End Sub
 
Естественно, добавить закрытие исследованной книги  
pBook.Close
 
Спасибо:)  
по этой строчке понимаю,что открывать придётся каждый файл  
Set pBook = Application.Workbooks.Open("d:\path\bookname.xls")  
Но вопрос,Уважаемый anvg,состоял:  
"Быть может есть код VBA умеющий определить о наличии макросов,форм в несколько сотен файлов?"  
 
Понимаю,что косяк мой был в их создании,но может есть ещё выход?
 
"код VBA умеющий определить о наличии макросов"  
То есть, принципиально не открывая? =)
 
А формат файлов какой - xls, xlsm?
 
А вы считаете, что это возможно, совсем без открытия файлов? Читать и проверять бинарную структуру VBA, пусть это и может быстрее, чем открытие файлов в Excel, но то же открытие. Ищите тогда информацию по бинарной структуре проектов VBA. На работе где то была ссылка, завтра посмотрю.  
Может пойти другим путём? Если у вас 2007, 2010, то можно открывать передаваемые файлы, сохранять в xlsx и потом по новой пересохранять в xls.  
Тут была такая тема - удаление всех макросов из книги с кодом этой операции.
 
Тоже нашел (не)Служебное произведение  
практика показывает: все равно никто не разберется даже с формулами, а с кодом тем более
 
Да дело не в том,что НЕслужебное произведение.  
Можно,конечно и "забить"на это с Вашего позволения.  
Большинство кодов делалось при помощи Специалистов планеты:)  
*Огромное всем спасибо:)  
Помните фразу Шакурова из фильма "Шерлок Холмс.Сокровища Агры":  
"Правосудие требует отдать золото людям не имеющим к нему никакого отношения":)  
Я не скупердяй,только когда я всё делал для себя другие чай-кофе дома гоняли:)  
Или штрафами меня наказывали.  
 
Просто удаление всех макросов из книги - да здесь,сам задавал  
http://www.planetaexcel.ru/forum.php?thread_id=30469  
 
Но прежде надо найти эти файлы..  
Спасибо за советы,Друзья - буду рыть:)
 
У меня вот что получилось (раньше с VBComponents не работал программно)  
 
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
 
Ссылка на спецификацию VBA.  
http://msdn.microsoft.com/en-us/library/cc313094(v=office.12).aspx  
Сам не смотрел, может и не то, у меня пока руки не дошли.  
Рекурсивное сканирование подпапок для поиска файлов Excel можно сзделать и в таком варианте (необходимо подключить библиотеку Microsoft Shell Controls And Automation).  
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
 
Огромное Вам спасибо,Уважаемый Казанский:)  
Всё работает:)  
 
Простите..а как указать:  
 
1)в этой строчке(или ниже в коде):  
Const FLDR = "c:\temp\1\"  
чтобы поиск был,включая подкаталоги заданной папки?  
 
2)в функции DeleteAllVBA:  
чтобы было удаление всех Userform и формул( то есть остались бы только данные?)  
 
Огромное спасибо за ответ:)
Страницы: 1
Читают тему
Наверх