Все же победил я его. Но может както лучше можно было его написать? или проще? Весь код:
Код
Option Explicit
Sub Search_through_Books()
'i& — скоращенноя форма записи As Long
Dim fileItem, openedWorkBook As Workbook, lastRowOfOpenedWb&, lastColumnOfOpenedWb&
Dim SearchRange As Range, Cell As Range, i&, j&
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = True
.Title = "Выберите нужные файлы удерживая Shift или Ctrl"
.Filters.Add "Excel files", "*.xls; *.xlsx; *.xlsm", 1
.ButtonName = "Start"
If .Show = -1 Then
Application.ScreenUpdating = False
Set SearchRange = ThisWorkbook.Worksheets("Источник").Range("A2:A" & _
ThisWorkbook.Worksheets("Источник").Cells(Rows.Count, "A").End(xlUp).Row)
For Each fileItem In .SelectedItems
Set openedWorkBook = Workbooks.Open(fileItem)
lastRowOfOpenedWb = openedWorkBook.Worksheets(1).Cells(Rows.Count, "C").End(xlUp).Row
For i = 1 To lastRowOfOpenedWb
If openedWorkBook.Worksheets(1).Cells(i, "C").Text Like "*" & ThisWorkbook.Worksheets("Источник").Range("A2").Text & "*" _
And openedWorkBook.Worksheets(1).Cells(i, "D").Text <> "Дебет" _
And openedWorkBook.Worksheets(1).Cells(i, "D").Text <> "Д" Then
lastColumnOfOpenedWb = openedWorkBook.Worksheets(1).Cells(i, Columns.Count).End(xlToLeft).Column
Range(openedWorkBook.Worksheets(1).Cells(i, 1), openedWorkBook.Worksheets(1).Cells(i, lastColumnOfOpenedWb)).Copy _
ThisWorkbook.Worksheets("Результат").Range("B1").Offset(j, 0)
ThisWorkbook.Worksheets("Результат").Range("A1").Offset(j, 0).Value = openedWorkBook.Name
j = j + 1
ElseIf openedWorkBook.Worksheets(1).Cells(i, "C").Text Like "*" & ThisWorkbook.Worksheets("Источник").Range("A2").Text & "*" _
And (openedWorkBook.Worksheets(1).Cells(i, "D").Text = "Дебет" _
Or openedWorkBook.Worksheets(1).Cells(i, "D").Text = "Д") Then
lastColumnOfOpenedWb = openedWorkBook.Worksheets(1).Cells(i, Columns.Count).End(xlToLeft).Column
Range(openedWorkBook.Worksheets(1).Cells(i, 1), openedWorkBook.Worksheets(1).Cells(i, lastColumnOfOpenedWb)).Offset(-2, 0).Copy _
ThisWorkbook.Worksheets("Результат").Range("B1").Offset(j, 0)
ThisWorkbook.Worksheets("Результат").Range("A1").Offset(j, 0).Value = openedWorkBook.Name
j = j + 1
End If
Next i
openedWorkBook.Close
Set openedWorkBook = Nothing
Next fileItem
End If
End With
Application.ScreenUpdating = True
End Sub
Народ, появилась необходимость дополнить код, в связи со следующим: Есть разрывы между таблицами (файнридер преобразовал таким образом) и иногда искомое слово оказалось на следующей странице, а значения (суммы) остались на предыдущей. Отследить это просто: Если искомое слово найдено, а в следующей ячейке (сдвиг вправо) нет значений "Дебет" или "Д", то копируем "этим кодом", если искомое слово найдено, а в следующей ячейке содержится "Дебет" или "Д", то копируем "этим же кодом но со сдвигом на две строки вверх" Я постарался написать, но что-то пошло не так. ПС я немного упростил предыдущий код, чтоб легче было читать (в часте поиска в двух столбцах). Вот что я изобразил (не забрасывайте тапками).
Код
For i = 3 To lastRowOfOpenedWb
If openedWorkBook.Worksheets(1).Cells(i, "C").Text Like "*" & ThisWorkbook.Worksheets("Источник").Range("A2").Text & "*" _
And openedWorkBook.Worksheets(1).Cells(i, "D").Text <> "Дебет" _
And openedWorkBook.Worksheets(1).Cells(i, "D").Text <> "Д" Then
lastColumnOfOpenedWb = openedWorkBook.Worksheets(1).Cells(i, Columns.Count).End(xlToLeft).Column
Range(openedWorkBook.Worksheets(1).Cells(i, 1), openedWorkBook.Worksheets(1).Cells(i, lastColumnOfOpenedWb)).Copy _
ThisWorkbook.Worksheets("Результат").Range("B1").Offset(j, 0)
ThisWorkbook.Worksheets("Результат").Range("A1").Offset(j, 0).Value = openedWorkBook.Nam
ElseIf openedWorkBook.Worksheets(1).Cells(i, "C").Text Like "*" & ThisWorkbook.Worksheets("Источник").Range("A2").Text & "*" _
And openedWorkBook.Worksheets(1).Cells(i, "D").Text = "Дебет" _
Or openedWorkBook.Worksheets(1).Cells(i, "D").Text <> "Д" Then
Range(openedWorkBook.Worksheets(1).Cells(i, 1), openedWorkBook.Worksheets(1).Cells(i, lastColumnOfOpenedWb)).Offset(-2, 0).Copy _
ThisWorkbook.Worksheets("Результат").Range("B1").Offset(j, 0)
ThisWorkbook.Worksheets("Результат").Range("A1").Offset(j, 0).Value = openedWorkBook.Name
j = j + 1
End If
Next i
Но не работает, я догадываюсь что это не работает мой Offset(-2, 0), а возможно что-то с самим условием, в часте операторов And и Or ПС2 в приложенном файле данная ситуация, слово для поиска "Тест"
Ігор Гончаренко, Игорь спасибо большое за критику. Не очень приятно. Не знаю что именно Вас так триггернуло, наверное что я сравнил свою всратую логику с машинной, постораюсь больше такого не делать. Что касается указанного мною вопроса, могу Вам ответить следующее: я честно разбирался все утро, но ответа не нашел. Я недавно начал погружаться в VBA, и иногда такие, казалось бы глупые моменты меня приводят в ступор. Я сразу не догадался, что дата заключенная кавычками понимается как текст и мне необходима была подсказка, а спросить неукаого кроме вас. VBA весьма жаден на подсказки, конечно мне было б легче, если среда мне подсказала, что в моем условии сравниваются разные типы данных.
Ребят помогите разобраться как работает условие If...Then. Вот допусти строчка кода:
Код
If Date > "01.01.2024" Then Exit Sub
По моей логике: системная дата > "01.01.2024" = ложь; значит идем по строчкам кода дальше. Но на практике это вырождение запускает Exit Sub. Then ведь выполняется при True. ПС. Забыл сказать что Date это не моя переменная.
Ребят помогите доделать. Вышеуказанный код прекрасно работает. Но появилась нужда в поиске не одного слова, а некого списка находящегося на листе "источник" А1...А. Я попробовал воткнуть счетчик в счетчик, но для меня это сложно. ПС, я для себя немного упростил код относительно последнего, чтоб легче было прописать вышекуазанное условие
Код
lastRowOfOpenedWb = openedWorkBook.Worksheets(1).Cells(Rows.Count,"A").End(xlUp).Row
For i = 1 To lastRowOfOpenedWb
lastActivRow =ThisWorkbook.Worksheets("Источник").Cells(Rows.Count, "A").End(xlUp).Row
For s = 1 To lastActivRow
If UCase(openedWorkBook.Worksheets(1).Cells(i,AE).Text) Like "*" & _
UCase(ThisWorkbook.Worksheets("Источник").Cells(s, A).Text) & "*" _
Then
openedWorkBook.Worksheets(1).Cells(i,"A").EntireRow.Copy ThisWorkbook.Worksheets("Результат").Range("A1").Offset(j, 0)
j = j + 1
End If
Next s
DANIKOLA, Помогите пожалуйста разобраться. Я хочу добавить имя файла первым столбцом в результат. Я объявил переменную Dim fileName As String. Сразу после строчки отвечающую за открытие очередного файла я "заполнил" переменную:
Код
Set openedWorkBook = Workbooks.Open(fileItem)
fileName = ActiveWorkbook.Name
А как вставить в результат эту переменную не могу разобраться. Если я правильно понимаю, нужно в эту строчку прикрутить мою переменную, и в рамках этого условия перед переходом к следующему файлу, эту переменную обнулить.
Доброго дня всем. Помогите пожалуйста доделать небольшой скрипт. Задача: открыть книгу где находится макрос, указать на листе "источник" слово или фразу в ячейке А2. Запустить макрос. Диалоговое окно в каких книгах искать - указываем, макрос стартует. Макрос ищет в столбцах C и D искомое слово или фразу (мне в голову кроме for each...Like ничего не пришло). Если находит совпадение, то копирует полностью строку на лист "Результат" книги откуда запущен макрос (Find). Перебором идем к следующей строке...следующей книге. Изначальные мои хотелки которые я пытался наваять в модуле: Хотел чтоб если я прогнал один раз макрос и он собрал какой то массив на листе результат, иметь возможность на листе "источник" заменить искомую конструкцию и стартануть макрос еще раз, и он, при наличии результата продолжил бы тот массив который был собран в первый раз.
Небольшое пояснение. Почему искать в C и D, а не просто в C. Потому что те книги где мы ищем совпадения, результат работы файнридера. Иногда файнридер разбивает колонку A или B, тогда колонка с наименованиями попросту съезжает на одну.
Доброго дня. Есть задача. Нужно просчитать штрафы. ЧТо имеем: 1) Диапазоны дат и ставка штрафа, эти данные постоянны. 2) Есть дата уплаты и сумма, эти данные меняются. Я в файле все условия расписал, но небольшое описание задачи оставлю сдесь. Ход решения как бы я делал это руками: 1) Смотрю на первую дату уплаты денег, допустим 25.04.2019 я заплатил. Чтоб рассчитать за какие конкретно дни штрафуюсь, я смотрю на следующую дату уплаты, допустим 25.05.2019. Вычитанием понимаю количество дней за которые меня штрафуют и конечную дату фиксирую так же рядом (чтоб использовать ее в формуле). Это 30 дней (но нужно всегда прибавлять 1 день, на самом деле я не знаю нахрена, но нужно). Сравниваем наш получившийся диапазон дат с диапазонами дат из константных данных, находим нашу строчку и берем оттуда ставку. Умножаем ставку на деньги и делим на 300. Кажется что это не сложно. Однако часто получившийся диапазон дат попадает в два константных диапазона и тут у меня начинаются проблемы. Посмотрите пожалуйста файл, я там расписал все. и ход ручного решения.
У меня единственная мысль, это в скрипт перевода в csv, вставить Columns("A:A").Replace What:=",,,,,,,,,,,", Replacement:="" Так как количество оставшихся запятых всегда одинаковое Ну это уже жесткие костыли.
Sanja, Прикрепляю исходный файл "пример исходник", код как его обрабатываю, и готовый макрос перевода в csv
Код
Sub Get_All_File_from_Folder()
Dim sFolder As String, sFiles As String
Dim wb As Workbook
On Error Resume Next
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = False Then Exit Sub
sFolder = .SelectedItems(1)
End With
sFolder = sFolder & IIf(Right(sFolder, 1) = Application.PathSeparator, "", Application.PathSeparator)
Application.ScreenUpdating = False
lLastRowThis = ThisWorkbook.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
sFiles = Dir(sFolder & "*.xls*")
Do While sFiles <> ""
Set wb = Application.Workbooks.Open(sFolder & sFiles)
Columns("B:AQ").Delete
Rows("1:3").Delete
Columns("A:A").Replace What:="~(Годен*", Replacement:=""
Columns("A:A").Replace What:="~(Без*", Replacement:=""
Range("A:A").RemoveDuplicates 1
wb.Close True
sFiles = Dir
Loop
Application.ScreenUpdating = True
End Sub
Sanja, Sanja, Ну руками не вариант, я пытаюсь своять скрипт для большого обьема фалов. Я думаю это можно поправить еще на этапе удаления столбцов и дубликатов строк.
Sanja, Это ксв файл, запятые в данном случае являются разделителями данных, в этом случае эти запятые говорят, что: ячейка существует но она пустая. Как будто значения ячеек удалились, но сами ячейки (пустые) осталичь
Sanja, А как выделить конечный результат без запятых, для экселя запятые это тоже значения. Почему Range("A:A").RemoveDuplicates 1 оставляет какие-то следы?
Проблема следующая. Кодом удаляю столбцы а потом в единственном оставшемся столбце удаляю дубликаты. Затем мне нужно перевести в csv. Когда перевожу в csv, понимаю, что удаленные столбцы и строки оставили следы их присутствия, наверное тип ячеек (но я не уверен). Вот эти кодом обрабатываю структуру:
Я подумал, и наверное одним из вариантов решения это: Сначала удалить целые конструкции, которые в любом случае и начинаются и заканчиваются на () и на [] А затем уже удалять обрубки которые только начинаются на ( и на [. и ими уже не закрываются.
Доброго дня. Задача во множестве файлов удалить колонки, строки, и часть теста в ячейках. После всего удалить дубликаты. В принципе со все понятно, кроме удаления части текста. У меня сложная ситуация с условиями удаления, которые я описал в прилагаемом файле. Сам код таков:
Код
Sub Get_All_File_from_Folder()
Dim sFolder As String, sFiles As String
Dim wb As Workbook
On Error Resume Next
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = False Then Exit Sub
sFolder = .SelectedItems(1)
End With
sFolder = sFolder & IIf(Right(sFolder, 1) = Application.PathSeparator, "", Application.PathSeparator)
Application.ScreenUpdating = False
lLastRowThis = ThisWorkbook.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Библиотека = ThisWorkbook.ActiveSheet.Range("A1:B" & lLastRowThis)
sFiles = Dir(sFolder & "*.xls*")
Do While sFiles <> ""
Set wb = Application.Workbooks.Open(sFolder & sFiles)
Columns("B:S").Delete
Rows("1:3").Delete
lLastRowOpen = wb.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
lLastColOpen = wb.ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
OpenFile = wb.ActiveSheet.Range("A1:A" & lLastRowOpen)
Columns("А1:А").Replace What:="~(*~)", Replacement:="" 'тут я столкнулся со сложностью
Range("A1:A").RemoveDuplicates 1, xlNo
wb.Close true
sFiles = Dir
Loop
Application.ScreenUpdating = True
End Sub