Добрый день! Решил написать макрос перемещения файлов, согласно списку в эксель файле. Тоесть есть папка с определённым количеством файлов, есть список, в котором указано имя некоторых файлов из той папки. Используя труды здешних обитателей, получил следующий макрос: [vba]
Код
Sub Сортировка1_перенос_файлов_по_перечню() 'раннее связывание, требуется ссылка на 'модель Windows Script Host Object Model Dim i As Long Dim ActWB As Workbook Dim avInp(), FSO As FileSystemObject, fl As File Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder As String
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolder = .SelectedItems(1) Else Exit Sub End With End If If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
For i1 = 1 To n For Each fl In .Files peremeshenie = 0 ' MsgBox (Cells(StrokaOtsch, Stolbec).Value & Chr(13) & fl.Name) If NameFile(i1) = fl.Name Then kol = kol + 1 ' MsgBox (FoldPth & fl.Name & Chr(13) & NewFolder)
peremeshenie = 1 End If If peremeshenie = 1 Then FSO.MoveFile FoldPth & fl.Name, FoldPth & NewFolder End If Next fl Next i1 End With End With Application.ScreenUpdating = True MsgBox ("Количество перемещённых файлов :" & kol) End Sub
[/vba] Работает крайне долго, если файлов порядка 14 000, а в таблице около 5000 имён. Можно ли это как-то исправить? И ещё интересует, вот если поменять так код:
[vba]
Код
For Each fl In .Files For i1 = 1 To n peremeshenie = 0 ' MsgBox (Cells(StrokaOtsch, Stolbec).Value & Chr(13) & fl.Name) If NameFile(i1) = fl.Name Then kol = kol + 1 ' MsgBox (FoldPth & fl.Name & Chr(13) & NewFolder)
peremeshenie = 1 End If If peremeshenie = 1 Then FSO.MoveFile FoldPth & fl.Name, FoldPth & NewFolder End If Next i1 Next fl
[/vba] Возможно ли исключение из цикла тех файлов, по которым перемещение уже произошло. Ато получается что внутренний цикл уже переместил файл, тобишь в исходном каталоге его уже нет. Внутренний цикл переходит на следующее повторение, а судя по внешнему циклу, мы будем искать тот файл который уже перемещён. Естественно - ошибка - файл не найден.
Добрый день! Решил написать макрос перемещения файлов, согласно списку в эксель файле. Тоесть есть папка с определённым количеством файлов, есть список, в котором указано имя некоторых файлов из той папки. Используя труды здешних обитателей, получил следующий макрос: [vba]
Код
Sub Сортировка1_перенос_файлов_по_перечню() 'раннее связывание, требуется ссылка на 'модель Windows Script Host Object Model Dim i As Long Dim ActWB As Workbook Dim avInp(), FSO As FileSystemObject, fl As File Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder As String
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolder = .SelectedItems(1) Else Exit Sub End With End If If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
For i1 = 1 To n For Each fl In .Files peremeshenie = 0 ' MsgBox (Cells(StrokaOtsch, Stolbec).Value & Chr(13) & fl.Name) If NameFile(i1) = fl.Name Then kol = kol + 1 ' MsgBox (FoldPth & fl.Name & Chr(13) & NewFolder)
peremeshenie = 1 End If If peremeshenie = 1 Then FSO.MoveFile FoldPth & fl.Name, FoldPth & NewFolder End If Next fl Next i1 End With End With Application.ScreenUpdating = True MsgBox ("Количество перемещённых файлов :" & kol) End Sub
[/vba] Работает крайне долго, если файлов порядка 14 000, а в таблице около 5000 имён. Можно ли это как-то исправить? И ещё интересует, вот если поменять так код:
[vba]
Код
For Each fl In .Files For i1 = 1 To n peremeshenie = 0 ' MsgBox (Cells(StrokaOtsch, Stolbec).Value & Chr(13) & fl.Name) If NameFile(i1) = fl.Name Then kol = kol + 1 ' MsgBox (FoldPth & fl.Name & Chr(13) & NewFolder)
peremeshenie = 1 End If If peremeshenie = 1 Then FSO.MoveFile FoldPth & fl.Name, FoldPth & NewFolder End If Next i1 Next fl
[/vba] Возможно ли исключение из цикла тех файлов, по которым перемещение уже произошло. Ато получается что внутренний цикл уже переместил файл, тобишь в исходном каталоге его уже нет. Внутренний цикл переходит на следующее повторение, а судя по внешнему циклу, мы будем искать тот файл который уже перемещён. Естественно - ошибка - файл не найден.Roman777
Много чего не знаю!!!!
Сообщение отредактировал Roman777 - Среда, 25.03.2015, 15:50
RAN, Спасибо ещё раз. Код действительно работает гораздо быстрее. Получается что программа быстрее определит существование файла, чем сравнит его имя с именем из таблицы?
RAN, Спасибо ещё раз. Код действительно работает гораздо быстрее. Получается что программа быстрее определит существование файла, чем сравнит его имя с именем из таблицы?Roman777
RAN, Но разве при проверке на существование, программе не приходится так же искать из 14000 файлов существующие 5000? и всё-равно получается при цикле по 5000 наименованиям, он каждое имя выискивает в 14000 файлах и определяет его существование, разве нет?
RAN, Но разве при проверке на существование, программе не приходится так же искать из 14000 файлов существующие 5000? и всё-равно получается при цикле по 5000 наименованиям, он каждое имя выискивает в 14000 файлах и определяет его существование, разве нет?Roman777
Хотел добавить, что я чуть-чуть изменил принцип, я все имена файлов сначала забил в массив, и после уже делал тож самое что в своём самом первом варианте (сравнение массивов). Результат - работает гораздо быстрее даже чем метод FSO.Fileexists. Только вчера понял что операции с массивами гораздо быстрее работают, чем с файлами...) Результат: [vba]
Код
Sub Сортировка2_перенос_файлов_по_перечню2() 'раннее связывание, требуется ссылка на 'модель Windows Script Host Object Model Dim i As Long Dim ActWB As Workbook Dim avInp(), FSO As FileSystemObject, fl As File Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder As String Dim ki As Long Dim Fiyli() As String
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
Time_1 = Timer With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolder = .SelectedItems(1) Else Exit Sub End With End If If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
ReDim Fiyly(.Files.Count) For Each fl In .Files ki = ki + 1 Fiyly(ki) = fl.Name Next fl
For i = 1 To UBound(Fiyly) For i1 = 1 To n If Fiyly(i) = NameFile(i1) Then kol = kol + 1 FSO.MoveFile FoldPth & NameFile(i1), FoldPth & NewFolder End If Next i1 Next i End With End With time_ = Time_1 - Timer Time_delta = Format(time_ / 24 / 60 / 60, "hh\ч mm\м ss\с") Application.ScreenUpdating = True MsgBox ("Выполнено за " & Time_delta & Chr(13) & "Количество перемещённых файлов :" & kol) End Sub
[/vba] Перенёс мне 5092 фотки за 10 секунд дето..)
Хотел добавить, что я чуть-чуть изменил принцип, я все имена файлов сначала забил в массив, и после уже делал тож самое что в своём самом первом варианте (сравнение массивов). Результат - работает гораздо быстрее даже чем метод FSO.Fileexists. Только вчера понял что операции с массивами гораздо быстрее работают, чем с файлами...) Результат: [vba]
Код
Sub Сортировка2_перенос_файлов_по_перечню2() 'раннее связывание, требуется ссылка на 'модель Windows Script Host Object Model Dim i As Long Dim ActWB As Workbook Dim avInp(), FSO As FileSystemObject, fl As File Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder As String Dim ki As Long Dim Fiyli() As String
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
Time_1 = Timer With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolder = .SelectedItems(1) Else Exit Sub End With End If If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
ReDim Fiyly(.Files.Count) For Each fl In .Files ki = ki + 1 Fiyly(ki) = fl.Name Next fl
For i = 1 To UBound(Fiyly) For i1 = 1 To n If Fiyly(i) = NameFile(i1) Then kol = kol + 1 FSO.MoveFile FoldPth & NameFile(i1), FoldPth & NewFolder End If Next i1 Next i End With End With time_ = Time_1 - Timer Time_delta = Format(time_ / 24 / 60 / 60, "hh\ч mm\м ss\с") Application.ScreenUpdating = True MsgBox ("Выполнено за " & Time_delta & Chr(13) & "Количество перемещённых файлов :" & kol) End Sub
[/vba] Перенёс мне 5092 фотки за 10 секунд дето..)Roman777
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") .................................
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolder = .SelectedItems(1) Else Exit Sub End With End If
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") .................................
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolder = .SelectedItems(1) Else Exit Sub End With End If
RAN, Весело...) ну хоть бы прокоментировали понятно. Я шутки не понимаю. Ранее почему-то это не казалось Вам смешным. Знаю в ВБА оч мало, поэтому наверное кажется так неуклюже. Тем не менее, код работает так, как мне нужно).
RAN, Весело...) ну хоть бы прокоментировали понятно. Я шутки не понимаю. Ранее почему-то это не казалось Вам смешным. Знаю в ВБА оч мало, поэтому наверное кажется так неуклюже. Тем не менее, код работает так, как мне нужно).Roman777
Комментирую. 1. Вы включаете секундомер, и идете из раздевалки к линии старта. Бежите 100 метров. На финише выключаете секундомер. За сколько вы пробежали 100 метров? Может есть смысл включить на старте? 2. При отсутствии папки новая папка добавляется в диалоге. Ну, и, до кучи, измерять время работы макроса секундами, это почти то-же, что измерять остаток бензина в баке легковушки ведрами.
PS раньше не обращал внимания. На таймере зацепился.
Комментирую. 1. Вы включаете секундомер, и идете из раздевалки к линии старта. Бежите 100 метров. На финише выключаете секундомер. За сколько вы пробежали 100 метров? Может есть смысл включить на старте? 2. При отсутствии папки новая папка добавляется в диалоге. Ну, и, до кучи, измерять время работы макроса секундами, это почти то-же, что измерять остаток бензина в баке легковушки ведрами.
PS раньше не обращал внимания. На таймере зацепился.RAN
Быть или не быть, вот в чем загвоздка!
Сообщение отредактировал RAN - Пятница, 27.03.2015, 19:24
RAN, Ещё раз спасибо! Блин, всё моя невнимательность. А я подумал, что я что-то совсем не там использую, думал что ограничения тут какие-то в FSO... из-за Вашей реакции. С таймером, Вы правы не туда поставил, но вроде потом же исправлял... по-ходу сюда не ту версию макроса копирнул. А вот с диалоговым окном, я задумывал, что если имя папки стереть, можно было бы папку для переносимых файлов назначить. Но тут действительно выглядит неправильно. Вроде подправил ошибки: [vba]
Код
Sub Сортировка2_перенос_файлов_по_перечню2() 'раннее связывание, требуется ссылка на 'модель Windows Script Host Object Model Dim i As Long Dim ActWB As Workbook Dim avInp(), FSO As FileSystemObject, fl As File Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder1, NewFolder As String Dim ki As Long Dim Fiyli() As String
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolderPath = .SelectedItems(1) Else: Exit Sub End With Else NewFolderPath = FoldPth & NewFolder End If
Time_1 = Timer If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
ReDim Fiyly(.Files.Count) For Each fl In .Files ki = ki + 1 Fiyly(ki) = fl.Name Next fl
For i = 1 To UBound(Fiyly) For i1 = 1 To n If Fiyly(i) = NameFile(i1) Then kol = kol + 1 FSO.MoveFile FoldPth & NameFile(i1), NewFolderPath End If Next i1 Next i End With End With time_ = Time_1 - Timer Time_delta = Format(time_ / 24 / 60 / 60, "hh\ч mm\м ss\с") Application.ScreenUpdating = True MsgBox ("Выполнено за " & Time_delta & Chr(13) & "Количество перемещённых файлов :" & kol) End Sub
[/vba] ПС,на моём мелком экране крайне трудно читать такой код. А как тут все делают "разворачивающийся список" для кода?
RAN, Ещё раз спасибо! Блин, всё моя невнимательность. А я подумал, что я что-то совсем не там использую, думал что ограничения тут какие-то в FSO... из-за Вашей реакции. С таймером, Вы правы не туда поставил, но вроде потом же исправлял... по-ходу сюда не ту версию макроса копирнул. А вот с диалоговым окном, я задумывал, что если имя папки стереть, можно было бы папку для переносимых файлов назначить. Но тут действительно выглядит неправильно. Вроде подправил ошибки: [vba]
Код
Sub Сортировка2_перенос_файлов_по_перечню2() 'раннее связывание, требуется ссылка на 'модель Windows Script Host Object Model Dim i As Long Dim ActWB As Workbook Dim avInp(), FSO As FileSystemObject, fl As File Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder1, NewFolder As String Dim ki As Long Dim Fiyli() As String
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolderPath = .SelectedItems(1) Else: Exit Sub End With Else NewFolderPath = FoldPth & NewFolder End If
Time_1 = Timer If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
ReDim Fiyly(.Files.Count) For Each fl In .Files ki = ki + 1 Fiyly(ki) = fl.Name Next fl
For i = 1 To UBound(Fiyly) For i1 = 1 To n If Fiyly(i) = NameFile(i1) Then kol = kol + 1 FSO.MoveFile FoldPth & NameFile(i1), NewFolderPath End If Next i1 Next i End With End With time_ = Time_1 - Timer Time_delta = Format(time_ / 24 / 60 / 60, "hh\ч mm\м ss\с") Application.ScreenUpdating = True MsgBox ("Выполнено за " & Time_delta & Chr(13) & "Количество перемещённых файлов :" & kol) End Sub
[/vba] ПС,на моём мелком экране крайне трудно читать такой код. А как тут все делают "разворачивающийся список" для кода?Roman777
Добрый день! Народ,помогите! Взял этот код Romana777, а VBA при пошаговом запуске начинает ругаться вот на эту строчку 'Dim avInp(), FSO As FileSystemObject, fl As File Ругается так: User-defined type not defined Подскажите, что нужно исправить?
Все, разобрался. Нужно в VBA ч/з меню Tools->References подключить Windows Script Host Object Model. Может для чайников конечно (каковым я и являюсь), но может кому-то время сэкономит.
Добрый день! Народ,помогите! Взял этот код Romana777, а VBA при пошаговом запуске начинает ругаться вот на эту строчку 'Dim avInp(), FSO As FileSystemObject, fl As File Ругается так: User-defined type not defined Подскажите, что нужно исправить?
Все, разобрался. Нужно в VBA ч/з меню Tools->References подключить Windows Script Host Object Model. Может для чайников конечно (каковым я и являюсь), но может кому-то время сэкономит.andrik0110
Сообщение отредактировал andrik0110 - Воскресенье, 05.02.2017, 22:24
andrik0110, Дело в том, что объект FileSystemObject содержится в библиотеке Scrrun.Dll. По умолчанию она у Вас не включена. Включить её можно в окне VBA->Tools-> References-> напротив "Microsoft Scripting Runtime" установить галочку. Тогда ругаться на неопознанный объект не будет.
Ну и вообще не обязательно так очевидно подключать библиотеку. Можно создать объект немного по-другому даже с выключенной галкой (вродебы поздним связыванием такой приём называют):
[vba]
Код
Sub Сортировка2_перенос_файлов_по_перечню2()
Dim i As Long Dim ActWB As Workbook Dim avInp(), fl As Object Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder1, NewFolder As String Dim ki As Long Dim Fiyli() As String
Set FSO = CreateObject("Scripting.FileSystemObject") 'FSO определяю тут по-другому
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolderPath = .SelectedItems(1) Else: Exit Sub End With Else NewFolderPath = FoldPth & NewFolder End If
Time_1 = Timer If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
ReDim Fiyly(.Files.Count) For Each fl In .Files ki = ki + 1 Fiyly(ki) = fl.Name Next fl
For i = 1 To UBound(Fiyly) For i1 = 1 To n If Fiyly(i) = NameFile(i1) Then kol = kol + 1 FSO.MoveFile FoldPth & NameFile(i1), NewFolderPath End If Next i1 Next i End With End With time_ = Time_1 - Timer Time_delta = Format(time_ / 24 / 60 / 60, "hh\ч mm\м ss\с") Application.ScreenUpdating = True MsgBox ("Выполнено за " & Time_delta & Chr(13) & "Количество перемещённых файлов :" & kol) End Sub
[/vba]
andrik0110, Дело в том, что объект FileSystemObject содержится в библиотеке Scrrun.Dll. По умолчанию она у Вас не включена. Включить её можно в окне VBA->Tools-> References-> напротив "Microsoft Scripting Runtime" установить галочку. Тогда ругаться на неопознанный объект не будет.
Ну и вообще не обязательно так очевидно подключать библиотеку. Можно создать объект немного по-другому даже с выключенной галкой (вродебы поздним связыванием такой приём называют):
[vba]
Код
Sub Сортировка2_перенос_файлов_по_перечню2()
Dim i As Long Dim ActWB As Workbook Dim avInp(), fl As Object Dim Stolbec As Integer Dim StrokaOtsch As Integer Dim NameFile() As String Dim FoldPth, NewFolder1, NewFolder As String Dim ki As Long Dim Fiyli() As String
Set FSO = CreateObject("Scripting.FileSystemObject") 'FSO определяю тут по-другому
NewFolder = Application.InputBox("Укажите имя папки, в которую необходимо перенести файлы", "Имя новой папки", _ "Файлы из списка") Stolbec = Application.InputBox("Укажите номер столбца, в котором находятся наименования файлов", "Номер столбца", _ "8") StrokaOtsch = Application.InputBox("Укажите номер строки, в которой находится шапка таблицы", _ "Номер строки", "1")
With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка для работы с файлами" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then FoldPth = .SelectedItems(1) Else Exit Sub End With
If NewFolder = "" Then With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Папка файлов по списку" .ButtonName = "Select": .AllowMultiSelect = False If .Show Then NewFolderPath = .SelectedItems(1) Else: Exit Sub End With Else NewFolderPath = FoldPth & NewFolder End If
Time_1 = Timer If Right(NewFolder, 1) <> "\" Then NewFolder = NewFolder & "\" If Right(FoldPth, 1) <> "\" Then FoldPth = FoldPth & "\"
ReDim NameFile(i1_n - StrokaOtsch) For i1 = 1 To i1_n - StrokaOtsch If Cells(StrokaOtsch + i1, Stolbec) <> "" Then n = n + 1 NameFile(n) = Cells(StrokaOtsch + i1, Stolbec) End If Next i1 ReDim Preserve NameFile(n) Set FSO = CreateObject("Scripting.FileSystemObject") With FSO If Not .FolderExists(FoldPth & NewFolder) Then .CreateFolder FoldPth & NewFolder 'создание каталога With .GetFolder(FoldPth) If .Files.Count = 0 Then MsgBox "Файлов в указанном пути не найдено", 48: Exit Sub 'проверка наличия файлов
ReDim Fiyly(.Files.Count) For Each fl In .Files ki = ki + 1 Fiyly(ki) = fl.Name Next fl
For i = 1 To UBound(Fiyly) For i1 = 1 To n If Fiyly(i) = NameFile(i1) Then kol = kol + 1 FSO.MoveFile FoldPth & NameFile(i1), NewFolderPath End If Next i1 Next i End With End With time_ = Time_1 - Timer Time_delta = Format(time_ / 24 / 60 / 60, "hh\ч mm\м ss\с") Application.ScreenUpdating = True MsgBox ("Выполнено за " & Time_delta & Chr(13) & "Количество перемещённых файлов :" & kol) End Sub