1

Тема: VBS: Отбирать в коллекцию папки по определенному фильтру

Добрый вечер!
Есть исходный каталог, в котором куча папок, название которых имеет структуру "yyyymmdd" (год-месяц-день). В каждой из этих папок еще куча разных подпапок с множеством разных файлов.
Необходимо отбирать определенные файлы с определенным содержимым и копировать их в заданную папку.
Проблема в следующем: данный отбор нужно делать не по всем папкам, а только по тем, названия которых начинаются на определенный "год-месяц" (например, "200501_").

Есть исходный скрипт, который делает отбор по всем папкам. Прочитав кучу статей и форумов, нашел вроде бы нужную функцию, но так как в скриптописании я новичок, никак не удается ее реализовать. Важное условие: решить поставленную проблему необходимо только с помощью VBS. Просьба помочь дописать скрипт.

Сам скрипт:

sFolder = "e:\Rezak\proba\2005\" 'путь до исходного каталога
dFolder = "e:\Rezak\proba\copy\" 'папка, в которую делается копия файлов, подходящих под критерии отбора.
filter = "200501*" 'нужно ли отдельно прописывать значение filter'а или достаточно указать его при вставке функции?

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(sFolder)
ShowSubFolders(oFolder)
Set oWshShell = Nothing
Set oFSO = nothing
Set oDataBase = nothing
Set oShell = nothing
WScript.quit

Sub ShowSubFolders(oFolder)
	'Set collFolders = oFolder.SubFolders 'было в оригинале
	Set collFolders = NewoFolder(collFolders, "200501*") 'вставка функции
	For Each oSubFolder In collFolders
	Set collFiles = oSubFolder.Files
	For Each oFile In collFiles
		If  oFSO.GetExtensionName (oFile.Path) = "doc" Then

			... 'вырезал критерии отбора содержимого файлов, чтоб сократить скрипт.

		End If
	Next
	ShowSubFolders(oSubFolder)
	Next
End Sub

' попытка реализовать функцию отбора папок, названия которых начинаются на определенный "год-месяц"

Function NewoFolder(collFolders, ByVal filter)
	'Dim collFolders As New Collection 'на некоторых форумах встречал использование данного выражения, но применить его не смог...
	Set NewoFolder = New Collection 'создаем новую коллекцию папок.
	Set collFolders = oFolder.SubFolders
	For Each oSubFolder In collFolders 'перебираем папки в коллекции папок.
		If oSubFolder.Name Like filter Then NewoFolder.Add oSubFolder 'если название папок начинается на значение, указанное в filter, тогда записываем эти папки в новую коллекцию папок.
	Next
End Function

2

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Mik пишет:

определенные файлы с определенным содержимым

 ... 'вырезал критерии отбора содержимого файлов, чтоб сократить скрипт.

А вот это зря. Иначе неясно, что делать.
Структуру сохранять или файлы в кучу сбрасывать? Если второе, при совпадении пишем счётчик или в игнор?

3

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

А вот это зря. Иначе неясно, что делать.
Структуру сохранять или файлы в кучу сбрасывать? Если второе, при совпадении пишем счётчик или в игнор?

Не совсем понятно, какое имеет значение, по каким условиям идет отбор самих файлов? Трудность заключается в том, чтобы в отбор шли не все папки, а определенные.
Если я правильно понял Ваш вопрос, то ответ на него: сбрасывать в кучу, при совпадении пишем счетчик. Но лучше приведу исходную процедуру Sub, которая выглядит вот так:

nCountSC = 0
nCountDOC = 0
nCountAllFiles = 0

Sub ShowSubFolders(oFolder)
	Set collFolders = oFolder.SubFolders
	For Each oSubFolder In collFolders
	Set collFiles = oSubFolder.Files
	For Each oFile In collFiles
		nCountAllFiles = nCountAllFiles + 1
		If  oFSO.GetExtensionName (oFile.Path) = "doc" Then
			nCountDOC = nCountDOC + 1
			Set File = oFSO.GetFile (oFile.Path)
			If not IsNull(ReadDOC(oFile.Path, "определенное_содержимое")) Then 'ReadDOC определяется отдельной функцией.
				oFSO.CopyFile oFile.Path, dFolder
				nCountSC = nCountSC + 1
			End If
		End If
	Next
	ShowSubFolders(oSubFolder)
	Next
End Sub

4 (изменено: Flasher, 2016-02-22 01:11:44)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Ладно, про отдельную функцию ясно. Возьмите за основу мой скрипт.
Вместо

Filt = Join(Split(FSO.OpenTextFile(List,,,-1).ReadAll, vbNewLine), ".*;") & ".*"
Set OutDisk = Shell.NameSpace(FSO.GetDriveName(ODir))

напишите

Filt = "*.doc"

В том скрипте сохраняется структура каталогов. Чтобы этого не делать, замените

    OutDir = FSO.BuildPath(ODir, Mid(Folder.Self.Path, LenID))
    If Not FSO.FolderExists(OutDir) Then OutDisk.NewFolder(Mid(OutDir, 4))
    T = 1 : Shell.NameSpace(OutDir).CopyHere Items, 280
  End If
  Items.Filter 73888, "*"

на

    T = 1 : Shell.NameSpace(ODir).CopyHere Items, 280
  End If
  Items.Filter 73888, "200501_*.*"

Хотя стоп, там же ещё проверка doc нужна. Тогда вместо

    T = 1 : Shell.NameSpace(ODir).CopyHere Items, 280

это:

    T = 1 : Dim F
    For Each F in Items
  I	  If Not IsNull(ReadDOC(F.Path, "определенное_содержимое")) Then 'ReadDOC определяется отдельной функцией.
        Shell.NameSpace(ODir).CopyHere F.Path, 280
   	  End If
    Next

5

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Уважаемый Flasher, если честно, не совсем понял Ваш скрипт: что такое и откуда берутся значения "Fd", "F"(аналог objFile из моего скрипта?), "T = 1"? "Items" у Вас массив - может ли он выступать в качестве коллекции файлов? Что означают числовые значения после "Items.Filter" (75968, 73888)?
Никак не могу понять, как все же прикрутить это к моему скрипту...
Отбирать приходится среди тысяч папок и миллионов файлов (число, которых никогда заранее неизвестно...) не только doc, а например, xml-файлы, из которых копируется значение какого-либо атрибута в БД. Просто я при необходимости докручиваю к своему скрипту необходимые (уже известные) выражения и функции. Поэтому не хотелось бы из-за отбора определенных папок менять всю основу.

6 (изменено: Flasher, 2016-02-23 17:27:12)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Так понятней?:

Option Explicit : Dim Shell, FSO, Depth, Chek, AllOptions, Flags

Const InDir    = "C:\InputDir"  ' папка-источник
Const OutDir   = "C:\OutputDir" ' папка-получатель
Const FiltFile = "*.doc;*.xml"  ' фильтр файлов
Const FiltFold = "200501*"      ' фильтр подпапок первого уровня

' Необходимая группа флагов фильтрации:
Const SHCONTF_FOLDERS = 32 ' папки
Const SHCONTF_NONFOLDERS = 64 ' не папки (файлы)
Const SHCONTF_INCLUDEHIDDEN = 128 ' скрытые несистемные элементы
Const SHCONTF_FASTITEMS = 8192 ' ускорение поиска (по индексации)
Const SHCONTF_INCLUDESUPERHIDDEN = 65536 ' скрытые системные элементы
Flags = SHCONTF_INCLUDEHIDDEN + SHCONTF_FASTITEMS + SHCONTF_INCLUDESUPERHIDDEN

' Опции для CopyHere
Const OCnt = 8   ' Дать файлу новое имя при совпадении с существующим
Const OYes = 16  ' Авто-подтверждение во всех потенциальных окнах
Const OPrB = 256 ' Отображать окно с прогресс-баром без имён
AllOptions = OCnt + OYes + OPrB  ' складываем

Const Title = " Копирование файлов по содержимому      "
Set Shell = CreateObject("Shell.Application")
Set FSO   = CreateObject("Scripting.FileSystemObject")
Depth = UBound(Split(InDir, "\")) ' запоминаем глубину папки-источника
FFolder InDir, Chek   ' вызываем основную процедуру
If Chek = 1 Then MsgBox "Выполнено!", 4160, Title Else _
MsgBox "Нет файлов с заданным содержимым!", 4144, Title

Sub FFolder(Folder, T)
  Dim Items, Max, Filt, Fold
  Max = UBound(Split(Folder, "\")) ' текущая глубина
  Set Folder = Shell.NameSpace(Folder)
  Set Items  = Folder.Items  ' объект с коллекцией элементов каталога
  If Max > Depth + 1 Then  ' Если глубже первого уровня
    Items.Filter Flags + SHCONTF_NONFOLDERS, FiltFile  ' отбираем только файлы
    If Items.Count Then  ' если в коллекции что-то есть
      Dim F, Ext
      For Each F in Items  ' проходимся по отобранным фильтрацией файлам
        Ext = LCase(FSO.GetExtensionName(F.Path)) ' расширение файла
        If Ext = "doc" Then
      	  If Not IsNull(ReadDOC(F.Path, "определенное_содержимое")) Then ' ReadDOC определяется отдельной функцией
            T = 1 ' запоминаем, что есть такие файлы
            Shell.NameSpace(OutDir).CopyHere F.Path, AllOptions 
       	  End If
        ElseIf Ext = "xml" Then
      	  If Not IsNull(ReadXML(F.Path, "определенное_содержимое")) Then ' ReadXML определяется отдельной функцией
            T = 1 ' запоминаем, что есть такие файлы
            Shell.NameSpace(OutDir).CopyHere F.Path, AllOptions
       	  End If
        End If
      Next
    End If
  End If : Filt = "*"  ' все каталоги
  If Max = Depth Then Filt = FiltFold  ' Если уровень глубины нулевой, то фильтруем
  Items.Filter Flags + SHCONTF_FOLDERS, Filt  ' меняем в фильтрации файлы на папки
  For Each Fold In Items : FFolder Fold.Path, T : Next  ' перебираем список подпапок
End Sub

7

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Так понятней?:

Гораздо понятнее - огромное спасибо за разжевывание!
Но столкнулся с проблемой: Ваш скрипт работает на отлично, но только если файлы лежат в папках, названия которых начинаются на определенный "год-месяц" (например, "200501_"). Если файлы лежат еще глубже, то скрипт их не видит.
Перечитывая в сотый раз свой первый пост, я не удивляюсь, что так вышло: хотел сказать одно, а получается, что сказал другое...
Попробую объяснить на примере: "...\2005\20050125\1354067546747\файл.xml", где
- ... - путь до исходного каталога;
- 2005 - исходная папка;
- 20050125 - папка со структурой "yyyymmdd" (год_месяц_день) - интересует отбор всех папок за конкретный месяц (в данном случае за первый), т.е. чтоб в отбор не шли папки, например, за третий месяц "20050325";
- 1354067546747 - папка с файлами (таких папок очень много - названия совершенно разные);
- файл.xml - один из файлов, с которым работаем (файлов также очень много - названия также совершенно разные).
Таким образом, файлы находятся не в папке с датой, а глубже... Можно ли как-то это учесть это в скрипте? Заранее благодарен!

8

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Поправил. Так?

9

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Поправил. Так?

Большое Вам человеческое спасибо за то, что тратите на меня своё время!
Сначала скрипт нигде не мог найти файлы: ни в папке-источнике, ни в папке с датой, ни глубже...
Решил поэкспериментировать - в строке:

If Max > Depth + 1 Then

знак "больше" заменил на "меньше":

If Max < Depth + 1 Then

отбор стал идти глубже первого уровня, но без фильтра "200501*"...

Потом решил закомментировать строки:

If Max > Depth + 1 Then
End If : Filt = "*" 

стал отбирать без фильтра "200501*", но также глубже первого уровня.
Плюс к этому, если в строке

Items.Filter Flags + SHCONTF_FOLDERS, Filt

заменить Filt на FiltFold,

Items.Filter Flags + SHCONTF_FOLDERS, FiltFold

тогда отбор ищет файлы только в папках "200501*", но глубже не опускается...

Стыдно сказать, но уже 2,5 часа сижу и не знаю, как поправить. Алгоритм такой:
- сначала в папке-источнике отбираем все папки, которые соответствуют фильтру "200501*";
- потом в каждой из этих отобранных папок выбираем все каталоги "*";
- затем в каждом из этих каталогов отбираем файлы "*.xml", с которыми потом работаем.

10

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Ничего там менять не надо, там всё верно (единственное - убрал .* в FiltFold).
Пути InDir, OutDir без '\' на конце, как у меня?

Mik пишет:

названия которых начинаются на определенный "год-месяц" (например, "200501_").

+

Mik пишет:

- 20050125 - папка со структурой "yyyymmdd"

+

Mik пишет:

но без фильтра "200501*"

Так знак подчёркивания есть или нет, я не могу понять? Зачем такая путаница?

11

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Ничего там менять не надо, там всё верно (единственное - убрал .* в FiltFold).
Пути InDir, OutDir без '\' на конце, как у меня?
Так знак подчёркивания есть или нет, я не могу понять? Зачем такая путаница?

Прошу прощения: знака подчеркивания нет, вместо него должна быть звездочка - правильный фильтр "200501*".
Но это не так важно, я правил фильтр папок на нужный.
Пути InDir, OutDir без '\' на конце, как у Вас. Хотя наличие данного знака никак на результат у меня не влияет.
Если ничего не менять, то постоянно пишет "Нет файлов с заданным содержимым!", хотя они есть.
Если всё же заменить "больше" на "меньше" в строке:

If Max > Depth + 1 Then

тогда результат меняется на "Выполнено!", НО в OutDir оказываются файлы и из "20050125", и из каталога "20050225", который не должен идти в отбор...

12

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Mik пишет:

Пути InDir, OutDir без '\' на конце, как у Вас. Хотя наличие данного знака никак на результат у меня не влияет.

Это пока не нашли причину. Добавлять его нельзя.

Mik пишет:

Если ничего не менять, то постоянно пишет "Нет файлов с заданным содержимым!", хотя они есть.

Скорее есть другая ошибка. Следует ещё разок скопировать скрипт в нынешнем виде. У меня всё работает.

Mik пишет:

Если всё же заменить "больше" на "меньше" в строке:

Ещё раз повторяю. Ничего в этой части менять нельзя, а уж тем более знак на обратный (это вообще нелогично).

13 (изменено: Mik, 2016-02-23 17:15:50)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Скорее есть другая ошибка. Следует ещё разок скопировать скрипт в нынешнем виде. У меня всё работает.

Если можно, проверьте, пожалуйста, на примере моего каталога "proba" (в нем 2 папки "2005" - папка-источник и "copy" - пустая папка-получатель; в "2005" тоже 2 папки: "20050111" и "20050225", в каждой из которых еще по две папки, в которых по одному "xml" файлу, два из которых содержат нужный атрибут).

После запуска у меня стабильно "Нет файлов с заданным содержимым!"
Заменив "больше" на "меньше" (я понимаю, что нелогично, но всё же...), в папке "copy" у меня оказывается 2 файла с атрибутом "correct", хотя один из них лежит в папке "20050225", которая не должна участвовать в отборе.

Post's attachments

proba.zip 2.71 kb, 2 downloads since 2016-02-23 

You don't have the permssions to download the attachments of this post.

14

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Убирайте код. Понял в чём была ошибка. Переставил строку с Max = ... куда следует.

15

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Убирайте код. Понял в чём была ошибка. Переставил строку с Max = ... куда следует.

Стабильно выдает "Нет файлов с заданным содержимым!" (теперь независимо от знака "больше"/"меньше")...

16

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Да забудьте уже про знак. Я протестировал скрипт и получил результат: E:\Rezak\proba\copy\349252719.xml.

+ Mik

17

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Да забудьте уже про знак. Я протестировал скрипт и получил результат: E:\Rezak\proba\copy\349252719.xml.

Результат верен! Нашел, где была ошибка у меня: впопыхах в папке-источнике опечатался с годом. Теперь всё работает! Огромное спасибо за помощь!
Подскажите, пожалуйста, еще один момент, пока вчера копался со скриптом обнаружил, что счетчик не работает теперь. В старом скрипте было:

nCountSC = 0
nCountSC = nCountSC + 1

Тут по аналогии не считает - всегда 0. Счетчик можно только к коллекции приделать, а с массивом он не работает?

18

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Сейчас счётчик переименования там автоматический. Будет Name - копия.xml, Name - копия (2).xml и т.д.

А просто счётчик для чего?

19

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

А просто счётчик для чего?

Раньше по окончании скрипт выводил окно:

text = MsgBox ("Всего файлов в подкаталогах: " & CStr(nCountAllFiles) & Chr(13) & "   - из них XML-файлов: " & CStr(nCountXML) & Chr(13) & "   - из них XML-файлов с коррекцией: " & CStr(nCountSC) & Chr(13) & "   - затраченное время: " & cStr(Int(sTime2 - sTime1)) & " мин.", 64, "Внимание!")

Ценность его заключалась в том, что можно было сравнивать количество обработанных файлов и время работы скрипта, допустим, на сервере и его локальном диске, и на машине, которая подключается к каталогам через сетевую шару (через ip, через сетевой диск...) - затем выбирать оптимальный вариант. Понятно, что наиболее оптимальным будет проводить скрипт на локальном диске сервера, но он далеко не всем бывает доступен.

20

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Ясно. Тогда объявляйте переменную nCountSC глобально, т.е. после xmlParser.
nCountSC = 0 внутри процедуры тут только всё испорит, нужно убрать.
Насчёт времени работы не понял. Какое к этому имеет отношение счётчик?
Второй строкой указывается Tm = Timer, а уже в конце MsgBox Timer - Tm.

И, кстати, забыл написать.

	Set xmlParser = CreateObject("MSXML2.DOMDocument")

Создавать объект следует единожды, где-нибудь под Set FSO ..., а не при каждом вызове функции.

21

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

nCountSC = 0 внутри процедуры тут только всё испорит, нужно убрать.
Насчёт времени работы не понял. Какое к этому имеет отношение счётчик?
Создавать объект следует единожды, где-нибудь под Set FSO ..., а не при каждом вызове функции.

nCountSC = 0 не внутри процедуры, а перед ней. Внутри сам подсчет: nCountSC = nCountSC + 1
А счетчик имеет самое непосредственное отношение ко времени работы скрипта: ведь замер времени может быть произведен на базе с допустим 100 000 файлов, а может быть с 150 000 файлов - следовательно и время будет разное. Просто замеры времени могут выполнять разные люди, которые могут не учитывать, что число файлов в базе может измениться.
Про создание объектов: учел и внес коррекцию. Еще раз отдельное спасибо!

22

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Mik пишет:

nCountSC = 0 не внутри процедуры, а перед ней

Тогда не вижу проблемы:

n = 0
counter : MsgBox n

Sub counter
	For i = 0 To 4
		n = n + 1
	Next
	If n = 5 Then counter
End Sub
Mik пишет:

ведь замер времени может быть произведен на базе с допустим 100 000 файлов, а может быть с 150 000 файлов - следовательно и время будет разное.

Разное оно может быть от разных обстоятельств, а не только от числа рассмотренных файлов.

23

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher огромнейшее спасибо за неоценимую помощь!

24 (изменено: Mik, 2016-02-23 20:17:31)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Еще забыл спросить: обязательно ли включать в скрипт команды?

Set Shell = nothing
Set FSO   = nothing
...
WScript.quit

И где лучше это делать: перед процедурой или в самом конце всего скрипта?

25

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Необязательно. А перед вызовом процедуры вообще нельзя.

26 (изменено: Mik, 2016-02-23 21:18:58)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Тогда не вижу проблемы

Прошу извинить еще раз, но столкнулся всё же с проблемой на отрезке:

If Not IsNull(ReadXML(F.Path, "correct")) Then ' ReadXML определяется функцией
	T = 1 ' запоминаем, что есть такие файлы
	rNom = ReadXML(F.Path, "regNo")
	Cors = ReadXML(F.Path, "correct")
	If nCountSC > 0 Then sRN = sRN & ";" & sCS & chr(13)
	sRN = sRN & Replace(Ltrim(Replace(rNom,"0"," "))," ","0")
	sCS = Replace(Cors,",",";",1,-1)
	'Shell.NameSpace(OutDir).CopyHere F.Path, AllOptions
End If

Поясняю: старый скрипт использовался не только для копирования файлов, но чаще всего для получения определенных значений и записи их в CSV-файл (без копирования исходных файлов - поэтому в примере строку копирования закомментировал). Как записать в CSV знаю, но как их теперь отобрать, не понимаю. Раньше для этого использовался счетчик внутри процедуры (nCountSC). Как быть теперь?

27

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Mik пишет:

но как их теперь отобрать

Конкретней, пож-та.

28 (изменено: Mik, 2016-02-23 21:43:08)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher если

If nCountSC > 0 Then sRN = sRN & ";" & sCS & chr(13)

заменить на

sRN = sRN & ";" & sCS & chr(13)

или вместо nCountSC > 0 поставить T
То файл CSV выходит с пустым содержанием...
Может быть нужно каждую переменную дописать к

Dim Items, Max, Filt, Fold

?
До процедуры прописал:

sRN = ""
sCS = ""

29

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Не нужно присваивать пустые значения. Я же писал, что достаточно объявить переменные глобально.
От счётчика тут вообще никакого толку. Главное, что запись попала под условие.
Плюс ко всему никто не мешает дописывать новые строки в файл:

Dim CSV : Set CSV = FSO.OpenTextFile("C:\Test.csv", 8, True)

Sub FFolder(Folder, T)
    '...........
	CSV.WriteLine Replace(Ltrim(Replace(rNom,"0"," "))," ","0") & ";" & Replace(Cors,",",";")
End Sub

30

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Плюс ко всему никто не мешает дописывать новые строки в файл

Прописал переменные глобально и добавил строки в файл. При компиляции ошибка "Требуется объект CSV".
Set CSV находится ведь вне процедуры (в процедуру прописать нельзя - "разрешение отклонено")...

31

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Какие переменные? Тут только одна глобальная переменная - CSV. В процедуре открывать файл на запись и не надо, он же один.

32

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Тут только одна глобальная переменная - CSV. В процедуре открывать файл на запись и не надо, он же один.

Глобальные переменные перечисляются после "Option Explicit : Dim ..."  Если сюда добавляю CSV, тогда на строке

Dim CSV : Set CSV = FSO.OpenTextFile("C:\Test.csv", 8, True)

получаю ошибку "имя было переопределено"...

33

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Глобальные можно объявлять где угодно вне процедур и функций единожды.
Соответственно, если указывать в перечислении, то от 'Dim CSV :' нужно избавиться.

+ Mik

34

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Глобальные можно объявлять где угодно вне процедур и функций единожды.
Соответственно, если указывать в перечислении, то от 'Dim CSV :' нужно избавиться.

Спасибо за еще одно пояснение!
Глобальную переменную CSV объявил единожды, но всё же ошибка "Требуется объект: CSV" на строке

CSV.WriteLine Replace(Ltrim(Replace(rNom,"0"," "))," ","0") & ";" & Replace(Cors,",",";")

о чем уже писал в 30 посте.

35

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Я понимаю. Но такое может произойти только при условии добавочного объявления внутри процедуры или закрытии/очищении объекта CSV.

36 (изменено: Mik, 2016-02-24 00:04:25)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher пишет:

Я понимаю. Но такое может произойти только при условии добавочного объявления внутри процедуры или закрытии/очищении объекта CSV.

Добавочного объявления внутри процедуры нет:

Dim Items, Max, Filt, Fold, rNom, Cors

Закрытие/очищение объекта CSV тоже отсутствует - такой строки в файле нигде нет:

Set CSV = nothing

37

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Никакого запрета на запись в корень С: нет? Такой скрипт работает?:

Option Explicit
Const File = "C:\Test.csv"
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
Dim CSV : Set CSV = FSO.OpenTextFile(File, 8, True)
Dim n : WrText : CSV.Close
GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}").document.Application._
NameSpace(FSO.GetParentFolderName(File)).ParseName(FSO.GetFileName(File)).Verbs.Item(0).DoIt

Sub WrText
	n = n + 1
	CSV.WriteLine n & ";Текст;"
	If n < 10 Then WrText
End Sub

38 (изменено: Mik, 2016-02-24 21:34:32)

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher, огромнейше благодарен за Ваше желание помочь и разобраться!
К сожалению, на работе Интернет заблокирован, поэтому прочитал Ваш пост только сейчас. Зато на работе нашлось время для работы над скриптом. Нашел свою ошибку: Set-ы и другие переменные, которые участвуют в процедуре, нужно прописывать до вызова самой процедуры, а у меня было прописано после. Никак не мог понять, что процедура, в отличии от функции, начинается не с Sub, а раньше. Теперь хорошо это усвоил и сразу решилась куча проблем! Отдельное спасибо за Ваши пояснения к скрипту! Поэтому нужно добавить к Вашему комментарию:

Но такое может произойти только при условии добавочного объявления внутри процедуры или закрытии/очищении объекта CSV.

Или при условии открытия объекта CSV после вызова самой процедуры.

Единственное, что осталось еще нерешенным, так это подсчет числовых значений в атрибуте "correct". Как получать значения видно в посте 26, как их просто записать в CSV показано в Вашем посте 29. Но необходимо вклинить между двумя нижепредставленными значениями третье:

CSV.WriteLine Replace(Ltrim(Replace(rNom,"0"," "))," ","0") & ";" & Replace(Cors,",",";")

Как его получить долго ломал голову. Суть в том, что значения атрибута "correct" могут иметь вид "3", а могут "1, 5, 7, 15, 9, 12". Необходимо посчитать их количество и вывести такой результат: 1 - для первого случая и 6 - для второго. Ничего лучше не придумал, как если по-умолчанию будет выводиться 1, а после очищаем все числовые значения, считаем число запятых и прибавляем их к значению по-умолчанию. Но с помощью чего это реализовать, да еще чтоб можно было вклинить в одну строчку кода выше, даже не представляю...

39

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

CSV.WriteLine Replace(Ltrim(Replace(rNom,"0"," "))," ","0") & ";" & Ubound(Split(Cors, ", ")) + 1 & ";" & Replace(Cors,",",";")

40

Re: VBS: Отбирать в коллекцию папки по определенному фильтру

Flasher, Вы гений! Низкий Вам поклон и миллион благодарностей!