Страницы: 1
RSS
Парсинг Excel-файлов
 
Привет, Планета!

Опять нужна Ваша помощь.
Есть куча Excel-файлов с кучей формул.
Надо макросом найти и скопировать все формулы в отдельную книгу в виде таблицы:
"Имя книги-листа-ячейки" - "Значение" - "Формула без знака '='".

Т.е. получить нужный результат можно, задав на поиск в каждой книге символ "=". Скрин.
Но его нельзя сохранить или вывести на лист.
Понимаю, что нужно как-то зациклить поиск с выборкой результатов в массив и потом вывести массив на лист.
Вроде всё просто, но при температуре почти 40º не могу сообразить - мозг просто плавится.

SOS!!!
 
макет формирования

Код
Sub formula28()
Dim j1, j1k, j2, j2k, s1
   j1 = 0
   j1k = 20

   Do While j1 < j1k
      j1 = j1 + 1
      j2 = 0
      j2k = 20

      Do While j2 < j2k
         j2 = j2 + 1
         s1 = Cells(j1, j2).Formula
         ''FormulaR1C1

         If Mid(s1 & " ", 1, 1) = "=" Then
            Debug.Print j1, j2, Mid(s1, 2)
         End If
      Loop
   Loop
End Sub
 
Код
Sub t()
  Dim x As Range, c As Range, i&
  Set x = Sheets(1).UsedRange.SpecialCells(xlCellTypeFormulas, 23)
  If Not x Is Nothing Then
    For Each c In x.Cells
      i = i + 1
      Sheets(2).Cells(i, 1).Value = Mid(c.Formula, 2)
    Next
  End If
End Sub
Изменено: ikki - 29.06.2013 05:02:47
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
galina mur, ikki, LightZ, огромное Вам спасибо!
Попытался сделать универсальный макрос для поиска текста/формул в указанных xls*-файлах.
Выдаёт результат в виде Файл - Лист - Ячейка - Формула - Значение.
В информационных строках прописывает запрос, путь, число найденных результатов и время выполнения.
Осталось 2 вопроса:
Изменено: Acid Burn - 06.07.2013 12:59:40
 
Еще желательно добавить цикл по всем листам
И для быстроты занести в массив, а потом выгрузить результат на лист
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
1. Почитайте справку про методы FileDialog'a
2. Используйте булевую переменную
Ps. Почему Вы изменяете своё сообщение, а не пишете новое?
Ведь если тема будет подыматься вверх - шансов, что Вам помогут больше.
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
LightZ, через FileDialog у меня не получилось, про булевую переменную вообще не понял.
Можно пример кода?
Цитата
Почему Вы изменяете своё сообщение, а не пишете новое?
Просто не люблю засорять темы - потом самому же сложно перечитывать.
 
Если изменяете так, что в последующих сообщениях искажается смысл или теряется привязка, то мусора становится больше. Обращайте на это вимание.
Нужно учитывать, что посетители не перечитывают сообщения каждый раз при входе в тему и могут быть не в курсе новостей, которыми Вы напичкаете старые сообщения. Править/дополнять можно и нужно, но с умом.
 
Acid Burn,
1. С помощью FileDialog(msoFileDialogFilePicker) - зажимаете шифт и выделяете нужные Вам файлы или сразу все через Ctrl+A.
2. Пример кода можно.
Покажите какой результат у Вас сейчас и какой должен быть.
Также приложите часть кода, где выполняется нужный этап.
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Так-то "результат" был выложен в посте #4.
Вот код:
Код 1

Код 2
Изменено: Acid Burn - 06.07.2013 23:26:51
 
А нужный результат Вы так и не приложили...
Т.е. Вам нужно, чтобы названия листов и книг не дублировалось и просто были пустые ячейки?
Если да - тогда необходимо вынести запись имён листа и книги за цикл Do.

Код
 
lLR = iShFound.Cells(Rows.Count, 4).End(xlUp).Row + 1
iShFound.Cells(lLR, 2) = iWB.Name                ' Имя файла (при переходе от файла к файлу)
iShFound.Cells(lLR, 3) = iSh.Name                         ' Имя листа (при переходе от листа к листу)
Do
   With iShFound
      iLastRow = .Cells(.Rows.Count, 4).End(xlUp).Row + 1
      .Cells(iLastRow, 4) = iRng.Address            ' Адрес ячейки
      .Cells(iLastRow, 5) = Mid(iRng.Formula, 2)    ' Формула
      .Cells(iLastRow, 6) = iRng                    ' Значение
   End With
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
LightZ, Вы меня абсолютно правильно поняли.
Но выносить запись имён листа и книги за цикл Do я уже пробовал - работает не правильно.
С FileDialog тоже тромб... Похоже придётся рисовать форму и использовать Shell... (?)
 
1. Подумайте логически - как может работать неправильно?))
просто сделайте 2 переменные последней строки
2. Что не получается? Почему не подходит filedialog ?
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
1. Забыл изменить имя переменной.
Теперь всё работает! Простите за невнимательность!
2. При работе с папкой, содержащей несколько файлов Excel, хотелось бы получить:
а) возможность выбрать несколько файлов
б) возможность выбрать только 1 файл
в) автоматическую блокировку открытия файла-источника макроса (при его случайном выборе)
Сейчас работает только вариант "а)".
 
Такое чувство, что Вы читаете мои сообщения через строку или же вообще не читаете.
Цитата
LightZ пишет:
Acid Burn ,
1. С помощью FileDialog(msoFileDialogFilePicker) - зажимаете шифт и выделяете нужные Вам файлы или сразу все через Ctrl+A.
это а) и б)
насчет в) ничего не понял
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
LightZ, вот моя тестовая папка:
Выборка.xlsb - файл с макросом поиска; Тест - папка с 2-мя файлами (01, 02).
Попробуйте выбрать только поиск по файлу 01 - это будет пункт б), и он не работает.
Затем попробуйте поместить в папку Тест файл Выборка.xlsb - это будет пункт в).
 
Посмотрел. А зачем вообще использовать Dir?
Ведь можно сделать всё намного проще и обойтись только FileDialog'ом
См. пример:
Код
Sub io()
    Dim i&
    With Application.FileDialog(msoFileDialogFilePicker)
        .Show: If .SelectedItems.Count = 0 Then Exit Sub
        For i = 1 To .SelectedItems.Count
            MsgBox .SelectedItems(i)
        Next
    End With
End Sub
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Кстати, да. Спасибо Вам, LightZ! Я что-то и не подумал.
В новой версии:
1. Перестроил и сократил код
2. Ускорил очистку листа, заменил True/False на 0/1 (надеюсь, не перестарался)
3. Ввёл выдачу формул на русском
4. Добавил обработчик ошибок
5. Прикрутил более точный таймер
Прогнал в реальных условиях: 246940 результатов за 05:03:626 мин. (~813 опер./сек.). Медленно...

LightZ, в посте #5 Вы предлагали предварительно занести данные в массив.
Как это сделать?
Изменено: Acid Burn - 11.07.2013 09:44:58
 
Цитата
Acid Burn пишет: 2. Ускорил очистку листа, заменил True/False на 0/1 (надеюсь, не перестарался)
Что?  :|

По поводу массивов, вот пример:
Код
Dim aValues(), aFormuls()
aFormuls = Лист1.UsedRange.FormulaLocal
aValues = Лист1.UsedRange.Value
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
>> Что?
В смысле я заменил очистку 1048576 строк на очистку UsedRange.
В логических операторах ввёл 0/1 вместо True/False, т.к. цифровые значения в VBA обрабатываются быстрее.
Просто объединил в один пункт. :)
>> aValues(), aFormuls()
Тут не понял.
Можно поподробнее?
 
А что именно не понятно?
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Не могу понять, как использовать - ни зачитать, ни выгрузить в Excel.
С массивами у меня туго.
 
Всё просто, вот пример:
Код
Option Base 1
Sub tt()
    Dim aValues(), aFormuls()
    Dim i&, j&
    Rem заносим в массив значения и формулы
    With Лист1.UsedRange
        aValues = .Value
        aFormuls = .FormulaLocal
    End With
    Rem проходим циклом по строкам и столбцам массивов
    For i = 1 To UBound(aFormuls)
        For j = 1 To UBound(aFormuls, 2)
            If aFormuls(i, j) <> Empty Then
                Debug.Print aValues(i, j), " - значение"
                Debug.Print aFormuls(i, j), " - формула"
                Debug.Print Cells(i, j).Address, " - адрес"
            End If
        Next
    Next
End Sub

В данном примере адрес можно получить только если в A1 есть значение.
Ps. Советую почитать
Изменено: LightZ - 11.07.2013 23:24:33
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
LightZ, почитать и понять - разные вещи.
На всё нужно время...
За пример спасибо, правда адаптировать его не смог, только больше запутался.
В принципе, 5 минут на 246940 результатов - не так уж и плохо.
Предлагаю закрыть тему.
 
Один замечательный человек помог кардинально улучшить мой макрос.
Теперь для любого количества файлов Excel можно получить:
1. Всю информацию в соответствии с запросом на одном листе
2. Перечень уникальных функций и операторов
3. Перечень уникальных формул (последовательностей функций)
4. Проанализировать, какие функции/формулы/операторы используются чаще всего

Надеюсь, кому-то пригодится.
Страницы: 1
Читают тему
Наверх