Описание: Есть выгруженныe файлы отчета в excel (5 листов по 200-300 строк в каждом). Необходимо имеющиеся в них данные перенести в один новый файл exel. Пример во вложении
Примечания: Сделал вариант с "Send" разделив на несколько операций обработки, но обрабатывается все равно долго и не всегда корректно
Вот, как-то так. Считается, что в отчетах после строчки со статусом OK идет строчка со статусом PROBLEM, а еще что время записано в первой колонке, продолжительность - в пятой, статус - в третьей и первая строчка не содержит информации.
Код:
#include <Array.au3>#include <File.au3>#include <Excel.au3>Dim$aTotal[0][4]; Конечный массив$iCount=0; Переменная для конечного массива$sPath=@ScriptDir; Путь к папке с файлами Excel$sTotalName="Итог.xlsx"; Название итогового файла Excel$aList=_FileListToArray($sPath,'*.xlsx'); Берем список xlsx файлов в папке_ArrayDelete($aList,$sTotalName); Удаляем из этого списка название итогового файла, если он есть$oExcel=_Excel_Open(); Открываем Excel$iTotalTime=0For$iFile=1ToUBound($aList)-1; Для каждого файла...$oBook=_Excel_BookOpen($oExcel,$sPath&"\"&$aList[$iFile])$aRange=_Excel_RangeRead($oBook); Читаем в массив содержимое файла ExcelFor$iRow=1ToUBound($aRange)-1; Проходим по каждой строчке массива, первую строчку пропускаемIf$aRange[$iRow][2]=""ThenContinueLoop; Пропускаем пустые строкиIf$aRange[$iRow][2]="OK"Then; Записываем в конечный массив, если статус (третья строчка) = OKReDim$aTotal[$iCount+1][4]; Расширяем массив$aTotal[$iCount][0]=_ToDate($aRange[$iRow+1][0]); Записываем в первую колонку дату в следующей строчке$aTotal[$iCount][1]=_ToDate($aRange[$iRow][0]); Во вторую колонку - дату в текущей строчке$aTotal[$iCount][2]="PROBLEM"; На место статуса (третья колонка) записываем Problem$aTotal[$iCount][3]=$aRange[$iRow+1][4]; В четвертую колонку записываем Duration;ConsoleWrite($aRange[$iRow+1][4] & ' ' & _ToSecond($aRange[$iRow+1][4]) & @CRLF)$iTotalTime=$iTotalTime+_ToSecond($aRange[$iRow+1][4])$iCount=$iCount+1EndIfNext_Excel_BookClose($oBook); Закрываем книгуNextReDim$aTotal[$iCount+1][4]; Запишем общее время$aTotal[$iCount][3]=_SecondToTime($iTotalTime)$aTotal[$iCount][2]="Всего: "$oBook=_Excel_BookOpen($oExcel,$sPath&"\"&$sTotalName); Открываем итоговый файлIf@errorThen$oBook=_Excel_BookNew($oExcel); Или создаем новый_Excel_RangeWrite($oBook,$oBook.Activesheet,$aTotal,"A1"); Записать массив в книгу_Excel_BookSaveAs($oBook,$sPath&"\"&$sTotalName); Сохранить книгу под именем итогового файлаFunc_ToSecond($sTime); Переводит строку с временем в секунды. Например, из строки 3m 49s вернет 229$aTime=StringSplit($sTime,' ',2)$iValue=0For$iTime=0ToUBound($aTime)-1$sTmp=StringRight($aTime[$iTime],1)$aTime[$iTime]=StringTrimRight($aTime[$iTime],1)Switch$sTmpCase'd'$iValue=$iValue+$aTime[$iTime]*86400Case'h'$iValue=$iValue+$aTime[$iTime]*3600Case'm'$iValue=$iValue+$aTime[$iTime]*60Case's'$iValue=$iValue+$aTime[$iTime]EndSwitchNextReturn$iValueEndFuncFunc_ToDate($sStr); У меня Excel читает даты примерно как 20180418235301 , эта функция меняет формат даты обратноReturnStringLeft($sStr,4)&'-'&StringMid($sStr,5,2)&'-'&StringMid($sStr,7,2)_&' '&StringMid($sStr,9,2)&':'&StringMid($sStr,11,2)&':'&StringRight($sStr,2)EndFuncFunc_SecondToTime($iSecond); Формирует время из секунд, из 123 вернет 0.00:02:03 . Костыльно, конечно, но все жеIf$iSecond>=86400Then$iTmp=Floor($iSecond/86400)$iValue=$iTmp&'.'$iSecond=$iSecond-$iTmp*86400Else$iValue='0.'EndIfIf$iSecond>=3600Then$iTmp=Floor($iSecond/3600)If$iTmp<10Then$iValue=$iValue&'0'&$iTmp&':'EndIf$iValue=$iValue&$iTmp&':'$iSecond=$iSecond-$iTmp*3600Else$iValue=$iValue&'00:'EndIfIf$iSecond>=60Then$iTmp=Floor($iSecond/60)If$iTmp<10Then$iValue=$iValue&'0'EndIf$iValue=$iValue&$iTmp&':'$iSecond=$iSecond-$iTmp*60Else$iValue=$iValue&'00:'EndIfIf$iSecond>10ThenReturn$iValue&$iSecondElseReturn$iValue&'0'&$iSecondEndIfEndFunc
Могу выслать на почту так как excel формат загрузить нельзя
Добавлено:
Сообщение автоматически объединено:
Обьясню всю сложность данной процедуры. Изначально файлs скачивается с браузера c расширением CSV. Далее я открываю его Либеро он предлагает разбить его на поля, соглашаюсь затем сохраняю этот файл в формате excel, после этого удаляю файлы Либеро, в среднем выгружается около 10 файлов. Затем захожу в каждый файл добовляю столбец и переношу время в соответсттвии с примером затем изменяю формат значений 30s на 0,30 | 1m 30s на 1,30 | 1h 25m 30s на 85,30 | 1d 17h 15m 30s на 2475,30 . После этого суммирую время, затем удаляю ненужные столбцы, и так каждый файл количество строк в файле различное от 2 до 500 после того как обработал каждый файл беру шаблон отчета и забиваю туда данные с каждого файла отчет имеет два раздела. вверху указывается сумма времени по узлам по мощности и физикии она переводится в проценты 4 столбца. А внизу идет детализированный отчет в котором указано время начало время завершения продолжителность имя узла и тип (мощность либо физика). Один небольшой отчет занимает около 2 с половиной часов времени по одному филиалу а их более 25. отчет ежемесячный. :(
Добавлено:
Сообщение автоматически объединено:
Версию autoit обновил до 3.3 скрипт начал отрабатывать но не захватывает информацию со всех файлов результат примерно такой ! строка:
2018--0-4- 16: 1:45 2018--0-4- 16: 1:15 PROBLEM 11m 30s
Всего: 0.04:4:18:59
Со временем как бы непонятно
Добавлено:
Сообщение автоматически объединено:
Положил в рабочюю директорию один файл, исхдник и результат обработки во вложении. Исходник выше результат ниже
Добавлено:
Сообщение автоматически объединено:
Вот два исходных файла и отчет. Отчет по другим файлам создан поэтому цифры не соответствуют
С этого надо было начинать. Теперь скрипт ищет файлы CSV, в которых данные находятся в одной ячейке в каждой строке и записывает их в файл Итог.xlsx. С файлами CSV, что были в архиве, работает нормально.
Код:
#include <Array.au3>#include <File.au3>#include <Excel.au3>Dim$aTotal[0][4]; Конечный массив$iCount=0; Переменная для конечного массива$sPath=@ScriptDir; Путь к папке с файлами Excel$sTotalName="Итог.xlsx"; Название итогового файла Excel$aList=_FileListToArray($sPath,'*.csv'); Берем список xlsx файлов в папке_ArrayDelete($aList,$sTotalName); Удаляем из этого списка название итогового файла, если он есть$oExcel=_Excel_Open(); Открываем Excel$iTotalTime=0For$iFile=1ToUBound($aList)-1; Для каждого файла...$oBook=_Excel_BookOpen($oExcel,$sPath&"\"&$aList[$iFile])$aRange=_Excel_RangeRead($oBook); Читаем в массив содержимое файла ExcelFor$iRow=1ToUBound($aRange)-1Step2; Проходим по каждой строчке массива, первую строчку пропускаемIf$aRange[$iRow]=""ThenContinueLoop; Пропускаем пустые строки$aSplit=StringSplit($aRange[$iRow],',',3)$aNext=StringSplit($aRange[$iRow+1],',',3);_ArrayDisplay($aNext)ReDim$aTotal[$iCount+1][4]; Расширяем массив$aTotal[$iCount][0]=$aNext[0]; Записываем в первую колонку дату в следующей строчке$aTotal[$iCount][1]=$aSplit[0]; Во вторую колонку - дату в текущей строчке$aTotal[$iCount][2]="PROBLEM"; На место статуса (третья колонка) записываем Problem$aTotal[$iCount][3]=_SecondToMinutes(_ToSecond($aNext[4])); В четвертую колонку записываем Duration$iTotalTime=$iTotalTime+_ToSecond($aNext[4])$iCount=$iCount+1Next_Excel_BookClose($oBook); Закрываем книгуNextReDim$aTotal[$iCount+1][4]; Запишем общее время$aTotal[$iCount][3]=_SecondToMinutes($iTotalTime)$aTotal[$iCount][2]="Всего: "$oBook=_Excel_BookOpen($oExcel,$sPath&"\"&$sTotalName)If@errorThen$oBook=_Excel_BookNew($oExcel)_Excel_RangeWrite($oBook,$oBook.Activesheet,$aTotal,"A1")_Excel_BookSaveAs($oBook,$sPath&"\"&$sTotalName)Func_SecondToMinutes($iSecond); Переводит секунды в минуты в формате MM,SSIf$iSecond>=60Then$iTmp=Floor($iSecond/60)&','$iSecond=$iSecond-$iTmp*60Else$iTmp=0&','EndIfIf$iSecond>10ThenReturn$iTmp&$iSecondElseReturn$iTmp&'0'&$iSecondEndIfEndFuncFunc_ToSecond($sTime); Переводит строку с временем в секунды. Например, из строки 3m 49s вернет 229$sTime=StringReplace($sTime,'"','')$aTime=StringSplit($sTime,' ',2)$iValue=0For$iTime=0ToUBound($aTime)-1$sTmp=StringRight($aTime[$iTime],1)$aTime[$iTime]=StringTrimRight($aTime[$iTime],1)Switch$sTmpCase'd'$iValue=$iValue+$aTime[$iTime]*86400Case'h'$iValue=$iValue+$aTime[$iTime]*3600Case'm'$iValue=$iValue+$aTime[$iTime]*60Case's'$iValue=$iValue+$aTime[$iTime]EndSwitchNextReturn$iValueEndFunc