Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] CMD/BAT - Скрипт, который считывает количество данных из разных таблиц Excel (http://forum.oszone.net/showthread.php?t=334404)

romfus 19-04-2018 14:04 2809748

CMD/BAT - Скрипт, который считывает количество данных из разных таблиц Excel
 
Добрый день. Вот такая задачка. Имеются несколько десятков excel файлов с разными именами 34S_1 - 999999_19.04.2018_14.xls, 34S_400000 - 400138_19.04.2018_1.xls, 34S_400139 - 404622_19.04.2018_9.xls например. В каждой из этих таблиц имеются данные ( индекса городов ) Можно ли сделать так чтобы при запуске скрипта выводилось сообщение - Введите индекс и после ввода индекса выводилось количество данных с этим индексом со всех xls файлов? Думаю имена файлов xls неважно? Достаточно просто с:/путь/*.xls указать

Iska 19-04-2018 14:08 2809749

Цитата:

Цитата romfus
Думаю имена файлов xls неважно? Достаточно просто с:/путь/*.xls указать »

То есть, подразумевается, что мы перебираем все Рабочие книги в указанном каталоге, так?

Цитата:

Цитата romfus
Имеются несколько десяткой excel файлов »

Упакуйте несколько образцов файлов в архив и приложите к сообщению, либо выложите на обменник/Яндекс.Диск.

Цитата:

Цитата romfus
выводилось количество данных с этим индексом »

Что подразумевается под «количеством данных»?

romfus 19-04-2018 14:15 2809751

Вложений: 1
Вот пример одного файла, структура у них у всех одинакова. Так да, перебираем все рабочие книги. Посмотрите пример файла, думаете поймете о чем я. В файле много индексов. вводим один индекс и скрипт считывает сколько раз этот индекс повторился в книге и выдает количество

romfus 19-04-2018 14:23 2809754

Вложений: 1
вот 2 файл для примера

Iska 19-04-2018 16:04 2809797

Цитата:

Цитата romfus
Вот пример одного файла, »

Ну, почему, почему всегда одно и то же, одно и то же. Вам так сложно упаковать несколько разных файлов в архив и выложить?


Цитата:

Цитата romfus
повторился в книге »

Вы хотели сказать «в книгах»?

Ну, вот как-то так я себе это представляю (на WSH):
Скрытый текст
Код:

Option Explicit

Const adOpenStatic    = 3
Const adLockOptimistic = 3
Const adCmdText        = 1


Dim strSourceFolder
Dim strPostCode

Dim objFSO
Dim objFile

Dim objConnection
Dim objCatalog
Dim objTable
Dim objRecordset

Dim intTotalOccuped


If WScript.Arguments.Count = 1 Then
        strSourceFolder = WScript.Arguments.Item(0)
       
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
       
        If objFSO.FolderExists(strSourceFolder) Then
                strPostCode = "123456"
                strPostCode = InputBox("Введите почтовый индекс:", "Введите почтовый индекс", strPostCode)
               
                Set objConnection = WScript.CreateObject("ADODB.Connection")
                Set objRecordset  = WScript.CreateObject("ADODB.Recordset")
                Set objCatalog    = WScript.CreateObject("ADOX.Catalog")
               
                WScript.Echo "Почтовый индекс [" & strPostCode & "] встречается в:"
                WScript.Echo "------------------------------------------------------------------"
               
                intTotalOccuped = 0
               
                For Each objFile In objFSO.GetFolder(strSourceFolder).Files
                        If StrComp(objFSO.GetExtensionName(objFile.Name), "xls", vbTextCompare) = 0 Then
                                WScript.Echo "[" & objFile.Path & "]"
                               
                                With objConnection
                                        .Provider = "Microsoft.Jet.OLEDB.4.0"
                                        .Properties.Item("Extended Properties").Value = "Excel 8.0;HDR=Yes;IMEX=1"
                                        .Open objFile.Path
                                       
                                        objCatalog.ActiveConnection = objConnection
                                       
                                        For Each objTable In objCatalog.Tables
                                                If StrComp(objTable.Type, "TABLE", vbTextCompare) = 0 Then
                                                        With objRecordset
                                                                .Open "SELECT indexto FROM [" & objTable.Name & "] WHERE indexto = '" & strPostCode & "'", objConnection, adOpenStatic, adLockOptimistic, adCmdText
                                                                intTotalOccuped = intTotalOccuped + .RecordCount
                                                                WScript.Echo vbTab & "[" & objTable.Name & "] - " & .RecordCount & " раз(а)"
                                                                .Close
                                                        End With
                                                End If
                                        Next
                                       
                                        objCatalog.ActiveConnection = Nothing
                                       
                                        .Close
                                End With
                        End If
                Next
               
                WScript.Echo "------------------------------------------------------------------"
                WScript.Echo "Всего " & intTotalOccuped & " раз(а)"
               
                Set objCatalog    = Nothing
                Set objRecordset  = Nothing
                Set objConnection = Nothing
        Else
                WScript.Echo "Source folder [" & strSourceFolder & "] not found."
                WScript.Quit 2
        End If
Else
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptFullName & """ <Source folder>"
        WScript.Quit 1
End If

WScript.Quit 0



Путь к целевому каталогу указывается аргументом скрипта. Скорректируйте строку подключения под Ваш драйвер OLEDB. В случае x64 ОС и x86 версии драйвера (как, например, в моём примере) используйте x86-версию исполнителя cscript.exe из каталога %SystemRoot%\SysWOW64.

Iska 20-04-2018 06:26 2809917

Поправил недоработку в предыдущем сообщении, оставшуюся от отладки (не везде заменил прямой константный путь на переменную strSourceFolder).

romfus 20-04-2018 14:20 2810037

Спасибо. Что-то у меня cscript не запускается.

Iska 20-04-2018 14:23 2810040

Цитата:

Цитата romfus
Что-то у меня cscript не запускается. »

Продемонстрируйте.

romfus 20-04-2018 14:29 2810041

Цитата:

Цитата Iska
Продемонстрируйте. »

Iska, я скорее всего неправильно понял что-то. При запуске скрипта выдает Echo "Usage: cscript.exe //nologo """ & WScript.ScriptFullName & """ <Source folder>"

Iska 20-04-2018 14:38 2810045

Цитата:

Цитата romfus
выдает Echo "Usage: cscript.exe //nologo """ & WScript.ScriptFullName & """ <Source folder>" »

В сказки не верю. Покажите скриншот.

Цитата:

Цитата romfus
При запуске скрипта »

Опишите/продемонстрируйте, как Вы его запускаете.

romfus 20-04-2018 14:43 2810049

Вложений: 1
Цитата:

Цитата Iska
Опишите/продемонстрируйте, как Вы его запускаете. »

Я ваш код скопировал в текстовый файл сохранил как vbs и при запуске такая ошибка. Видимо я что-то опустил. Я просто в wsh не силен. Что-то видимо нужно где-то еще дополнительно указать, чего я не сделал как я понял

Iska 20-04-2018 14:54 2810052

Цитата:

Цитата romfus
Я ваш код скопировал в текстовый файл сохранил как vbs »

Здесь правильно.

Цитата:

Цитата romfus
и при запуске такая ошибка. »

Это сообщение о том, как следует осуществлять запуск скрипта правильно.

Откройте командную строку. Напишите в ней cscript.exe //nologo, добавьте пробел. Перетащите туда же скрипт из Проводника, добавьте ещё пробел. Теперь перетащите туда же из Проводника папку, в которой находятся файлы, которые требуется обработать. Нажмите Enter.

Если увидите сообщение вида «ADODB.Properties: Не удается найти указанный поставщик. Вероятно, он установлен неправильно» и у Вас x64 ОС — пишете не просто cscript.exe, а %SystemRoot%\SysWOW64\cscript.exe и т.д.

romfus 20-04-2018 15:01 2810054

Цитата:

Цитата Iska
Здесь правильно. »

Спасибо работает. А можно ли
R34ROMANOVSKIY4 C:\Users\Alexander.Romanovski>cscript.exe //nologo C:\Users\Alexander.Romanovski\Des
ktop\0001.vbs D:\IVC\Operators\Printer\20.04.2018
Закрепить в самом скрипте? чтобы при запуске сразу выводилось окно с просьбой ввести индекс?

Iska 20-04-2018 15:08 2810057

romfus, Вы хотите сказать, что каталог с файлами всегда будет один и тот же? Создайте ярлык вида:
Код:

C:\Windows\System32\cscript.exe //nologo "C:\Users\Alexander.Romanovski\Desktop\0001.vbs" "D:\IVC\Operators\Printer\20.04.2018"

romfus 20-04-2018 15:17 2810062

Цитата:

Цитата Iska
C:\Windows\System32\cscript.exe //nologo "C:\Users\Alexander.Romanovski\Desktop\0001.vbs" "D:\IVC\Operators\Printer\20.04.2018" »

а если созданный ярлык при запуске закрывается сразу? То есть появляется окно ввести индекс после ввода все счиытвает и моментально закрывается

Iska 20-04-2018 15:43 2810081

Цитата:

Цитата romfus
а если созданный ярлык при запуске закрывается сразу? То есть появляется окно ввести индекс после ввода все счиытвает и моментально закрывается »

Виноват, не подумал. Приношу Вам свои извинения.

Попробуйте задать такую строку в ярлыке:
Код:

"%comspec%" /c"C:\Windows\System32\cscript.exe //nologo "C:\Users\Alexander.Romanovski\Desktop\0001.vbs" "D:\IVC\Operators\Printer\20.04.2018" & pause"
Если требуются какие-либо манипуляции с окном — тогда так:
Код:

"%comspec%" /k"C:\Windows\System32\cscript.exe //nologo "C:\Users\Alexander.Romanovski\Desktop\0001.vbs" "D:\IVC\Operators\Printer\20.04.2018""
romfus, общий принцип и вид вывода — это то, что Вам требовалось? Более ничего менять/настраивать не надо?

romfus 20-04-2018 18:54 2810136

Все отлично. Спасибо!

megaloman 21-04-2018 15:56 2810229

romfus, Я, наверное, лезу не в своё дело, но постановку задачи я переосмыслил.
Я написал vbs-скрипт, который объединит в одну все Ваши таблицы,
Код:

inName = "Z:\Soft_In"

With WScript.Arguments
    If .Count <> 0 Then inName = .Item(0)
End With

Set FSO = CreateObject("Scripting.FileSystemObject")

On Error Resume Next
Set nDir = FSO.GetFolder(inName)
If Err.Number <> 0 Then
    MsgBox inName + vbCrLf + Err.Description
    WScript.Quit 1
End If
On Error GoTo 0

Tit = Array("num", "indexto", "region", "area", "city", "adres", "adresat", "mass", "value", "payment", "comment")
NTit = UBound(Tit) - LBound(Tit)

inExt = "xls"
Rng1 = "A1"
Rng2 = "B1"

Set AllFiles = nDir.Files

With CreateObject("Excel.Application")
    .Visible = True
    .Workbooks.Add

    CN = .Range(Rng1).Offset(0, NTit).Address
    .Range(Rng1 + ":" + CN).Value = Tit
    Cont = .Range(Rng2)
    ii = 0
       
    For Each iFile In AllFiles
        If LCase(inExt) = LCase(FSO.GetExtensionName(iFile)) Then
            .Workbooks.Open (iFile)
            i = 0
            If .Range(Rng2) = Cont Then
                Do
                    If Trim(.Range(Rng2).Offset(i + 1, 0)) = "" Then Exit Do
                    i = i + 1
                Loop
                R0 = .Range(Rng1).Offset(1, 0).Address
                RN = .Range(Rng1).Offset(i, NTit).Address
                Mas = .Range(R0 + ":" + RN)
            End If
            .ActiveWorkbook.Close
            .Range(R0 + ":" + RN).Offset(ii, 0).NumberFormat = "@"
            .Range(R0 + ":" + RN).Offset(ii, 0) = Mas
            ii = ii + i
        End If
    Next
    R0 = .Range(Rng2).Offset(1, 0).Address
    RN = .Range(Rng2).Offset(ii, 0).Address
    RF = .Range(Rng2).Offset(ii + 1, 0).Address
   
    .ActiveWindow.SplitRow = 1
    .ActiveWindow.FreezePanes = True
   
    .Columns("A:A").EntireColumn.AutoFit
    .Range(Rng2).AutoFilter
    .Range(RF).FormulaLocal = "=ПРОМЕЖУТОЧНЫЕ.ИТОГИ(3;" + R0 + ":" + RN + ")"
    .Rows(CStr(.Range(Rng2).Row)).Insert (xlDown)
    .Range(Rng2).FormulaLocal = "=" + .Range(RF).Offset(1, 0).Address

End With

затем накладывает на нее фильтр и прописывает формулу подсчета отфильтрованных значений. Если данных не слишком много, это сработает.
Что плохо в этом решении: конечно, сборка отработает медленнее. Я не знаю, сколько строк получится в итоговой таблице.
Что хорошо: после сборки при необходимости выборки нескольких индексов этот процесс быстр и удобен. Плюс, имеем полную инфу по каждому адресату. Можем выбирать сразу несколько индексов и подсчитывать их количество.
Можем выбрать инфу и по другому полю.
Обрабатываемую папку можно указать явно, например, как сейчас: inName = "Z:\Soft_In" (пропишИте своё!).
Однако, если при запуске скрипта папку указать в аргументе, то возьмётся не явное описание из текста скрипта, а то, что в аргументе.
Как следствие, на этот скрипт можно создать, например, на рабочем столе значок, и затягивать на него из проводника нужную папку .


Время: 15:29.

Время: 15:29.
© OSzone.net 2001-