Добрый день. Возникла необходимость в написании макроса, сам к сожалению только начал изучать данный вопрос.
Есть лист excel (рис.1). в нем указаны комплекты документов. В столбцах L-O сейчас руками созданы гиперссылки на необходимые папки. Есть папка на диске с входящими и исходящими письмами (рис.2). Папок и входящих и исходящих писем очень много, и в ручную каждый раз добавлять гиперссылки очень трудозатратно. Задача состоит в следующем, по нажатию кнопки делать проход по папкам и подпапкам, сравнивать наименование в столбце "B" листа excel и папках (рис3), и создавать столбцы с гиперссылками на папки.
Добрый день. Возникла необходимость в написании макроса, сам к сожалению только начал изучать данный вопрос.
Есть лист excel (рис.1). в нем указаны комплекты документов. В столбцах L-O сейчас руками созданы гиперссылки на необходимые папки. Есть папка на диске с входящими и исходящими письмами (рис.2). Папок и входящих и исходящих писем очень много, и в ручную каждый раз добавлять гиперссылки очень трудозатратно. Задача состоит в следующем, по нажатию кнопки делать проход по папкам и подпапкам, сравнивать наименование в столбце "B" листа excel и папках (рис3), и создавать столбцы с гиперссылками на папки.Ivan559455
Там 4 колонки с входящими\исходящими. Что куда вставлять? Вот код, он смотрит в одну папку и перебирает в ней файлы, сравнивая с кодом (конец строки до тире) и подкаталоги рекрсивно [vba]
Код
Sub GEGJ() Dim oWB As Workbook Dim rCell As Range, rSearchRange As Range Dim sFolder$, sCode$, sFileName$ Dim oFso As Object Dim oFolder As Object
Set oWB = ActiveWorkbook sFolder = "D:\" 'я пишу Д, вы свою 'Я пишу лист1, вы своё название листа Set rSearchRange = oWB.Sheets("Лист1").Range("B1:B" & Sheets("Лист1").Cells(Rows.Count, 2).End(xlUp).Row)
For Each rCell In rSearchRange If Not IsEmpty(rCell.Value) Then sCode = "-" & Right(rCell.Value, Len(rCell.Value) - InStrRev(rCell.Value, "-")) Set oFso = CreateObject("Scripting.FileSystemObject") Set oFolder = oFso.GetFolder(sFolder) Call RecursiveSubFolders(oFolder, sCode, oWB) Else Exit Sub End If Next rCell Set oFso = Nothing End Sub Sub RecursiveFiles(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook) Dim oFile As Object Dim sFilePath As String For Each oFile In oFolder.Files sFil = oFile.Name If InStr(oFile.Name, sCode) >= 1 Then sFilePath = oFile.Path oWB.Sheets("Лист1").Range("L" & rCell.Row) = "=HYPERLINK(" & sFilePath & ")" End If Next oFile End Sub Sub RecursiveSubFolders(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook) Dim oSubFolder As Object If oFolder.Subfolders.Count >= 1 Then For Each oSubFolder In oFolder.Subfolders Call RecursiveFiles(oFolder, sCode, oWB) If oFolder.Subfolders.Count >= 1 Then Call RecursiveSubFolders(oSubFolder, sCode, oWB) End If Next oSubFolder Else Call RecursiveFiles(oFolder, sCode, oWB) End If End Sub
[/vba]
Если надо в двух папках смотреть, то добавляете вокруг кода [vba]
Код
For Цикл = 1 to 2 Select Case Цикл 'сюда пишем для входящих Case 1: sFolder = "ваш путь" 'сюда пишем для исходящих Case 2: sFolder = "ваш путь" End Select 'А сюда код из основной процедуры Next Цикл
[/vba] И тогда ещё нужно передавать в подпроцедуры значение столбца куда ставить
Там 4 колонки с входящими\исходящими. Что куда вставлять? Вот код, он смотрит в одну папку и перебирает в ней файлы, сравнивая с кодом (конец строки до тире) и подкаталоги рекрсивно [vba]
Код
Sub GEGJ() Dim oWB As Workbook Dim rCell As Range, rSearchRange As Range Dim sFolder$, sCode$, sFileName$ Dim oFso As Object Dim oFolder As Object
Set oWB = ActiveWorkbook sFolder = "D:\" 'я пишу Д, вы свою 'Я пишу лист1, вы своё название листа Set rSearchRange = oWB.Sheets("Лист1").Range("B1:B" & Sheets("Лист1").Cells(Rows.Count, 2).End(xlUp).Row)
For Each rCell In rSearchRange If Not IsEmpty(rCell.Value) Then sCode = "-" & Right(rCell.Value, Len(rCell.Value) - InStrRev(rCell.Value, "-")) Set oFso = CreateObject("Scripting.FileSystemObject") Set oFolder = oFso.GetFolder(sFolder) Call RecursiveSubFolders(oFolder, sCode, oWB) Else Exit Sub End If Next rCell Set oFso = Nothing End Sub Sub RecursiveFiles(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook) Dim oFile As Object Dim sFilePath As String For Each oFile In oFolder.Files sFil = oFile.Name If InStr(oFile.Name, sCode) >= 1 Then sFilePath = oFile.Path oWB.Sheets("Лист1").Range("L" & rCell.Row) = "=HYPERLINK(" & sFilePath & ")" End If Next oFile End Sub Sub RecursiveSubFolders(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook) Dim oSubFolder As Object If oFolder.Subfolders.Count >= 1 Then For Each oSubFolder In oFolder.Subfolders Call RecursiveFiles(oFolder, sCode, oWB) If oFolder.Subfolders.Count >= 1 Then Call RecursiveSubFolders(oSubFolder, sCode, oWB) End If Next oSubFolder Else Call RecursiveFiles(oFolder, sCode, oWB) End If End Sub
[/vba]
Если надо в двух папках смотреть, то добавляете вокруг кода [vba]
Код
For Цикл = 1 to 2 Select Case Цикл 'сюда пишем для входящих Case 1: sFolder = "ваш путь" 'сюда пишем для исходящих Case 2: sFolder = "ваш путь" End Select 'А сюда код из основной процедуры Next Цикл
[/vba] И тогда ещё нужно передавать в подпроцедуры значение столбца куда ставитьVBAdevelope
Макросы VBA Excel, Word на заказ. Сказать спасибо на Юмани: 410015093172871
Сообщение отредактировал VBAdevelope - Понедельник, 17.04.2023, 17:05
VBAdevelope, Попробовал запустить Вам макрос, но ничего не произошло.
Поправил, нужно было передавать ещё область вставки + ссылку сделал обычным кодом. Вот для двух каталогов (1 входящий - вставляется в L; 2 - исходящий, вставляется в K). Из ячейки берётся sCode - с правого края текст формата "-символы-символы" без первого тире. По вашему ТЗ неясно, что должно происходить по нажатию кнопки, как выбирать столбцы для вставки ссылки, как вы собираете указывать папку поиска, заранее или каждый раз выбирать в файловой системе. Также неясно, что и куда добавлять, т.к. два столбца входящих и 2 исходящих. На данный момент макрос перебирает значения столбца "B" и отбирает последние символы до тире и ищет во всех папках любого уровня вложенности на диске "D:\" файлы с именем содержащим данные символы и копирует путь к файлу в столбец L. Подстроить код без допинформации не представляется возможным. Если папки (основные каталоги, в которых содержатся остальные подкаталоги) две, а столбец L Для входящи и K для исходящих, то код будет выглядеть так Ещё раз обращаю внимание, что вам нужно ввести название своего листа, пути к корневым каталогам и наименования столбцов, в которые ссылки будут вставляться - они отмечены комментариями.
[vba]
Код
Sub GetHyperlinksForFilesWithCodeNameFromB() Dim oWB As Workbook Dim rCell As Range, rSearchRange As Range Dim sFolder$, sCode$, sFileName$, sSheetName$, sVal$ Dim oFso As Object Dim oFolder As Object
Set oWB = ActiveWorkbook sSheetName = "Лист1" 'Я пишу лист1, вы своё название листа Set rSearchRange = oWB.Sheets(sSheetName).Range("B1:B" & Sheets(sSheetName).Cells(Rows.Count, 2).End(xlUp).Row)
For Each rCell In rSearchRange If Not IsEmpty(rCell.Value) Then sVal = rCell.Value sCode = Right(sVal, Len(sVal) - InStrRev(sVal, "-")) sVal = Left(sVal, Len(sVal) - Len(sCode) - 1) sCode = Right(sVal, Len(sVal) - InStrRev(sVal, "-")) & "-" & sCode For Цикл = 1 To 2 Select Case Цикл 'сюда пишем для входящих Case 1: sFolder = "D:\Входящие" 'Например "D:\Входящие\" sCol = "L" 'Столбец, куда будем вставлять 'сюда пишем для исходящих Case 2: sFolder = "D:\Исходящие" 'Например "D:\Исходящие\" sCol = "K" 'Столбец, куда будем вставлять End Select 'А сюда код из основной процедуры
Set oFso = CreateObject("Scripting.FileSystemObject") Set oFolder = oFso.GetFolder(sFolder) Call RecursiveSubFolders(oFolder, sCode, oWB, sCol, sSheetName, rCell) Next Цикл Else Exit Sub End If Next rCell Set oFso = Nothing End Sub
Sub RecursiveFiles(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook, _ ByVal sCol As String, ByVal sSheetName As String, ByRef rCell As Range) Dim oFile As Object Dim sFilePath As String For Each oFile In oFolder.Files sFil = oFile.Name If InStr(oFile.Name, sCode) >= 1 Then sFilePath = oFile.Path oWB.Sheets(sSheetName).Hyperlinks.Add Anchor:=oWB.Sheets(sSheetName).Range(sCol & rCell.Row), _ Address:=sFilePath, TextToDisplay:=Format(Date, "dd.mm.yyyy") End If Next oFile End Sub
Sub RecursiveSubFolders(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook, _ ByVal sCol As String, ByVal sSheetName As String, ByRef rCell As Range) Dim oSubFolder As Object If oFolder.Subfolders.Count >= 1 Then For Each oSubFolder In oFolder.Subfolders Call RecursiveFiles(oFolder, sCode, oWB, sCol, sSheetName, rCell) If oFolder.Subfolders.Count >= 1 Then Call RecursiveSubFolders(oSubFolder, sCode, oWB, sCol, sSheetName, rCell) End If Next oSubFolder Else Call RecursiveFiles(oFolder, sCode, oWB, sCol, sSheetName, rCell) End If End Sub
VBAdevelope, Попробовал запустить Вам макрос, но ничего не произошло.
Поправил, нужно было передавать ещё область вставки + ссылку сделал обычным кодом. Вот для двух каталогов (1 входящий - вставляется в L; 2 - исходящий, вставляется в K). Из ячейки берётся sCode - с правого края текст формата "-символы-символы" без первого тире. По вашему ТЗ неясно, что должно происходить по нажатию кнопки, как выбирать столбцы для вставки ссылки, как вы собираете указывать папку поиска, заранее или каждый раз выбирать в файловой системе. Также неясно, что и куда добавлять, т.к. два столбца входящих и 2 исходящих. На данный момент макрос перебирает значения столбца "B" и отбирает последние символы до тире и ищет во всех папках любого уровня вложенности на диске "D:\" файлы с именем содержащим данные символы и копирует путь к файлу в столбец L. Подстроить код без допинформации не представляется возможным. Если папки (основные каталоги, в которых содержатся остальные подкаталоги) две, а столбец L Для входящи и K для исходящих, то код будет выглядеть так Ещё раз обращаю внимание, что вам нужно ввести название своего листа, пути к корневым каталогам и наименования столбцов, в которые ссылки будут вставляться - они отмечены комментариями.
[vba]
Код
Sub GetHyperlinksForFilesWithCodeNameFromB() Dim oWB As Workbook Dim rCell As Range, rSearchRange As Range Dim sFolder$, sCode$, sFileName$, sSheetName$, sVal$ Dim oFso As Object Dim oFolder As Object
Set oWB = ActiveWorkbook sSheetName = "Лист1" 'Я пишу лист1, вы своё название листа Set rSearchRange = oWB.Sheets(sSheetName).Range("B1:B" & Sheets(sSheetName).Cells(Rows.Count, 2).End(xlUp).Row)
For Each rCell In rSearchRange If Not IsEmpty(rCell.Value) Then sVal = rCell.Value sCode = Right(sVal, Len(sVal) - InStrRev(sVal, "-")) sVal = Left(sVal, Len(sVal) - Len(sCode) - 1) sCode = Right(sVal, Len(sVal) - InStrRev(sVal, "-")) & "-" & sCode For Цикл = 1 To 2 Select Case Цикл 'сюда пишем для входящих Case 1: sFolder = "D:\Входящие" 'Например "D:\Входящие\" sCol = "L" 'Столбец, куда будем вставлять 'сюда пишем для исходящих Case 2: sFolder = "D:\Исходящие" 'Например "D:\Исходящие\" sCol = "K" 'Столбец, куда будем вставлять End Select 'А сюда код из основной процедуры
Set oFso = CreateObject("Scripting.FileSystemObject") Set oFolder = oFso.GetFolder(sFolder) Call RecursiveSubFolders(oFolder, sCode, oWB, sCol, sSheetName, rCell) Next Цикл Else Exit Sub End If Next rCell Set oFso = Nothing End Sub
Sub RecursiveFiles(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook, _ ByVal sCol As String, ByVal sSheetName As String, ByRef rCell As Range) Dim oFile As Object Dim sFilePath As String For Each oFile In oFolder.Files sFil = oFile.Name If InStr(oFile.Name, sCode) >= 1 Then sFilePath = oFile.Path oWB.Sheets(sSheetName).Hyperlinks.Add Anchor:=oWB.Sheets(sSheetName).Range(sCol & rCell.Row), _ Address:=sFilePath, TextToDisplay:=Format(Date, "dd.mm.yyyy") End If Next oFile End Sub
Sub RecursiveSubFolders(ByRef oFolder As Object, ByVal sCode As String, ByRef oWB As Workbook, _ ByVal sCol As String, ByVal sSheetName As String, ByRef rCell As Range) Dim oSubFolder As Object If oFolder.Subfolders.Count >= 1 Then For Each oSubFolder In oFolder.Subfolders Call RecursiveFiles(oFolder, sCode, oWB, sCol, sSheetName, rCell) If oFolder.Subfolders.Count >= 1 Then Call RecursiveSubFolders(oSubFolder, sCode, oWB, sCol, sSheetName, rCell) End If Next oSubFolder Else Call RecursiveFiles(oFolder, sCode, oWB, sCol, sSheetName, rCell) End If End Sub
По вашему ТЗ неясно, что должно происходить по нажатию кнопки, как выбирать столбцы для вставки ссылки, как вы собираете указывать папку поиска, заранее или каждый раз выбирать в файловой системе.
Есть файл эксель с наименованием комплектов, есть папка с письмами. По нажатию кнопки, должно происходить следующее: проход по каждой папке и поиск файлов в наименованиях которых есть тот или иной комплект, создание гиперссылки на папку в которой найден данный файл, (письма от разных дат) поэтому если при дальнейшем проходе по папкам обнаруживается еще файлы с наименованием того же комплекта, то записывается в соседний столбец. и так по всем папкам, подпапкам и комплектам. И еще вопрос, есть ли возможность гиперессылке сделать название в котором будет указана дата от какого числа данное письмо? Спасибо.
По вашему ТЗ неясно, что должно происходить по нажатию кнопки, как выбирать столбцы для вставки ссылки, как вы собираете указывать папку поиска, заранее или каждый раз выбирать в файловой системе.
Есть файл эксель с наименованием комплектов, есть папка с письмами. По нажатию кнопки, должно происходить следующее: проход по каждой папке и поиск файлов в наименованиях которых есть тот или иной комплект, создание гиперссылки на папку в которой найден данный файл, (письма от разных дат) поэтому если при дальнейшем проходе по папкам обнаруживается еще файлы с наименованием того же комплекта, то записывается в соседний столбец. и так по всем папкам, подпапкам и комплектам. И еще вопрос, есть ли возможность гиперессылке сделать название в котором будет указана дата от какого числа данное письмо? Спасибо.Ivan559455
Ещё подробнее нужно, вы хотите выполнять данную процедуру для одной строки, т.е для одного шифра (например того, ячейка которого активна в данный момент, если активна ячейка столбца Б)? Как определить, где папки с входящими, где с исходящими, они имеют одно и то же расположение на локальном диске или нет и сможете ли вы сами их указать? Должны ли гиперссылки располагаться по возрастанию дат от более старых к новым, если имеется несколько файлов во входящих\исходящих? Должны ли добавляться столбцы для гиперссылок, если найдено более 2 файлов для одного вида (входящие\исходящие)? Даты в наименовании подкаталога всегда содержатся в конце и имеют вид "от дата"?
Ещё подробнее нужно, вы хотите выполнять данную процедуру для одной строки, т.е для одного шифра (например того, ячейка которого активна в данный момент, если активна ячейка столбца Б)? Как определить, где папки с входящими, где с исходящими, они имеют одно и то же расположение на локальном диске или нет и сможете ли вы сами их указать? Должны ли гиперссылки располагаться по возрастанию дат от более старых к новым, если имеется несколько файлов во входящих\исходящих? Должны ли добавляться столбцы для гиперссылок, если найдено более 2 файлов для одного вида (входящие\исходящие)? Даты в наименовании подкаталога всегда содержатся в конце и имеют вид "от дата"?VBAdevelope
Макросы VBA Excel, Word на заказ. Сказать спасибо на Юмани: 410015093172871
Сообщение отредактировал Serge_007 - Вторник, 18.04.2023, 11:24
1. Операция нужна для всех строк, грубо говоря периодически будет необходимость нажать на кнопку что бы было понимание есть новые письма или нет, что бы оно обновлялось все скопом. 2. Папки с исходящими файлами имеют в начале наименования приписку ИСХ. Путь к папке указывается один раз. (папка для входящих и исходящих одно) 3. да гиперссылки должны быть по возрастанию дат. 4. Да столбцы должны добавляться (так как бывает очень много писем, которые по датам имеют огромный разброс) 5. Да в наименование папки и файлов указана дата.
Если есть еще вопросы по ТЗ, готов расписать. СПАСИБО.
1. Операция нужна для всех строк, грубо говоря периодически будет необходимость нажать на кнопку что бы было понимание есть новые письма или нет, что бы оно обновлялось все скопом. 2. Папки с исходящими файлами имеют в начале наименования приписку ИСХ. Путь к папке указывается один раз. (папка для входящих и исходящих одно) 3. да гиперссылки должны быть по возрастанию дат. 4. Да столбцы должны добавляться (так как бывает очень много писем, которые по датам имеют огромный разброс) 5. Да в наименование папки и файлов указана дата.
Если есть еще вопросы по ТЗ, готов расписать. СПАСИБО.Ivan559455
Сообщение отредактировал Serge_007 - Вторник, 18.04.2023, 11:54
1. Операция нужна для всех строк, грубо говоря периодически будет необходимость нажать на кнопку что бы было понимание есть новые письма или нет, что бы оно обновлялось все скопом.
То есть нужно будет периодически актуализировать данные, проводить сверку с имеющимися? А может ли быть такое, что старые письма были удалены, нужно ли тогда удалять старые ссылки? Не смущает ли вас большое число столбцов со ссылками? Возможно, если не выносить их в отдельный лист, то хотя бы реализовать возможность свернуть\развернуть эти столбцы по нажатию знака (+) вверху? Это необходимые сведения для ТЗ, но так или иначе это уже существенный объём и под оплату, поскольку займёт кусок времени. Это уже для раздела фриланс.
1. Операция нужна для всех строк, грубо говоря периодически будет необходимость нажать на кнопку что бы было понимание есть новые письма или нет, что бы оно обновлялось все скопом.
То есть нужно будет периодически актуализировать данные, проводить сверку с имеющимися? А может ли быть такое, что старые письма были удалены, нужно ли тогда удалять старые ссылки? Не смущает ли вас большое число столбцов со ссылками? Возможно, если не выносить их в отдельный лист, то хотя бы реализовать возможность свернуть\развернуть эти столбцы по нажатию знака (+) вверху? Это необходимые сведения для ТЗ, но так или иначе это уже существенный объём и под оплату, поскольку займёт кусок времени. Это уже для раздела фриланс.VBAdevelope
Макросы VBA Excel, Word на заказ. Сказать спасибо на Юмани: 410015093172871
Сообщение отредактировал VBAdevelope - Вторник, 18.04.2023, 11:50
в каком месте вы у меня усмотрели бессмысленное цитирование?
До того как я отредактировал Ваш пост он начинался с полного цитирования поста Ivan559455 Я убрал бессмысленное цитирование Что-то стало менее понятным?
Цитирование всего поста в несколько строк не несет в себе смысловой нагрузки, а просто задваивает информацию Цитирование предназначено исключительно для акцентирования внимания на каких то моментах из всего поста[/offtop]
в каком месте вы у меня усмотрели бессмысленное цитирование?
До того как я отредактировал Ваш пост он начинался с полного цитирования поста Ivan559455 Я убрал бессмысленное цитирование Что-то стало менее понятным?
Цитирование всего поста в несколько строк не несет в себе смысловой нагрузки, а просто задваивает информацию Цитирование предназначено исключительно для акцентирования внимания на каких то моментах из всего поста[/offtop]Serge_007
1. Да периодически нужна будет актуализация данных, но сообщения не удаляться, все письма храняться 2. Большое количество никак не смущает. 3. Свернуть/развернуть это вполне подходящее решение для большого количества столбцов. 4. Если это под оплату, то сколько это будет по деньгам?
VBAdevelope,
1. Да периодически нужна будет актуализация данных, но сообщения не удаляться, все письма храняться 2. Большое количество никак не смущает. 3. Свернуть/развернуть это вполне подходящее решение для большого количества столбцов. 4. Если это под оплату, то сколько это будет по деньгам?Ivan559455