Что нового

[Автоматизация] Корректировка файлов *.txt и с последующим сохранением в *.xls

NiceScript

Новичок
Сообщения
8
Репутация
0
Версия AutoIt: 3.3.14.2 -- 18.09.2015

Описание:
Программа позволит автоматизировать рутинные действие по преобразованию выходных данных после расчетов в одних специальных программах для их обработки в других специальных программах.

Алгоритм работы программы после запуска скрипта:
- найти все файлы *.txt в папке, из которой запущен скрипт (где лежит);
- преобразовать найденные файлы в экселевские файлы *.xls ( Ox.txt -> Ox.xls);
- сохранить новые экселевские файлы в папке, из которой запущен скрипт (где лежит);

Примечания:
Текстовые файлы представляют собой построчный набор чисел с разделителем "." произвольной длинны (от 1 до 10^6), пример для 13. Один из файлов прикладываю. Например с таким содержанием:

0.606217782649107
0.762484238517637
0.973021464970246
1.21243556529821
1.45184966562618

Готовые *.xls файлы представляют собой таблицу, в которой заполнен первый столбик числами из файлов *.txt.
Для выше приведенного примера, получится один столбик

0,606217783
0,762484239
0,973021465
1,212435565
1,451849666

Обратите внимание, что вместо "." в *.txt файлах, используется "," в *.xls файлах. Это позволяет воспринимать данные из *.xls в последующих программах, как числа, а не как текст.

Я обычно открывал каждый txt вручную, далее через поиск и замену, менял "." на ",", потом открывал в excel каждый *.txt и сохранял как *.xls (попутно указывая разделитель ","). Когда файлы пошли на десятки я стал задумываться, - а все ли правильно я делаю.

Надеюсь на вашу помощь! Спасибо, всем откликнувшимся.

Подготовил файлы для прикрепления, но не могу найти, как, тт
 
A

Alofa

Гость
Код:
#include <File.au3>
#include <Excel.au3>

Global $aFileList, $oExcel, $sText, $aText, $oWorkbook

$aFileList = _FileListToArray(@ScriptDir, '*.txt', $FLTA_FILES)
If @error Then Exit

$oExcel = _Excel_Open(False)
For $i = 1 To $aFileList[0]
	$sText = FileRead(@ScriptDir & '\' & $aFileList[$i])
	If @error Then ContinueLoop
	$aText = StringRegExp($sText, '(?m)(\d+\.\d+)\s*$', 3)
	If @error Then ContinueLoop
	For $j = 0 To UBound($aText) - 1
		$aText[$j] = StringReplace(Round($aText[$j], 9), '.', ',') ; Round() => округление до 9 символов после запятой
	Next
	$oWorkbook = _Excel_BookNew($oExcel)
	If @error Then ContinueLoop
	_Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $aText)
	If Not @error Then _Excel_BookSaveAs($oWorkbook, @ScriptDir & '\' & StringTrimRight($aFileList[$i], 3) & 'xls', $xlExcel8)
	_Excel_BookClose($oWorkbook, False)
Next
_Excel_Close($oExcel)
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
Спасибо, что откликнулись! С вашим текстом создал скрипт, поместил в папку, запустил *.a3x, ничего не произошло. Сделал *.exe, запустил его, ничего не произошло. Добавил в папку файлы File.au3, Excel.au3, после чего опять заново сделал и *.a3x, и *.exe - ничего не произошло.

Потом подумал, может программа заканчивает "Exit" - тут же это выход из программы? ДОбавил три сообщения тестовых, в итоге все три показались. Программа доходит до последней строчки.

Код:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile_type=a3x
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <File.au3>
#include <Excel.au3>

Global $aFileList, $oExcel, $sText, $aText, $oWorkbook
MsgBox(0, "Обучение", "Привет Мир! Начало")
$aFileList = _FileListToArray(@ScriptDir, '*.txt', $FLTA_FILES)
If @error Then Exit
MsgBox(0, "Обучение", "Привет Мир! Цикл пошел")
$oExcel = _Excel_Open(False)
For $i = 1 To $aFileList[0]
    $sText = FileRead(@ScriptDir & '\' & $aFileList[$i])
    If @error Then ContinueLoop
    $aText = StringRegExp($sText, '(?m)(\d+\.\d+)\s*$', 3)
    If @error Then ContinueLoop
    For $j = 0 To UBound($aText) - 1
        $aText[$j] = StringReplace(Round($aText[$j], 9), '.', ',') ; Round() => округление до 9 символов после запятой
    Next
    $oWorkbook = _Excel_BookNew($oExcel)
    If @error Then ContinueLoop
    _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $aText)
    If Not @error Then _Excel_BookSaveAs($oWorkbook, @ScriptDir & '\' & StringTrimRight($aFileList[$i], 3) & 'xls', $xlExcel8)
    _Excel_BookClose($oWorkbook, False)
Next
_Excel_Close($oExcel)
MsgBox(0, "Обучение", "Привет Мир!")


Сделал скриншот папки, но с моими правами запрещено давать ссылки. Разве, что вот так:
cdn3.savepice.ru/uploads/2017/3/10/24b04d0fd4e77e572c8ea60e5b9296ab-full.png
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
#include <Excel.au3>
Local $hSearch = FileFindFirstFile('*.txt')
If @error Then Exit MsgBox(16, 'Ошибка', 'Нет файлов txt')
Local $sFile, $sData, $aData, $oBook, $oExcel = _Excel_Open(False)
While 1
	$sFile = FileFindNextFile($hSearch)
	If @error Then ExitLoop

	$sData = FileRead($sFile) ;Читаем файл
	$sData = StringReplace($sData, '.', ',') ;Меняем точки на запятые
	$aData = StringSplit($sData, @CRLF, 1 + 2) ;Делаем массив

	$oBook = _Excel_BookNew($oExcel) ;Новая книга
	_Excel_RangeWrite($oBook, 1, $aData) ;запись массива
	_Excel_BookSaveAs($oBook, @ScriptDir & '\' & $sFile & '.xls', $xlExcel8) ;сохранение как xls
	_Excel_BookClose($oBook, False) ;Закрытие
WEnd
_Excel_Close($oExcel)
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
inververs сказал(а):
Код:
#include <Excel.au3>
Local $hSearch = FileFindFirstFile('*.txt')
If @error Then Exit MsgBox(16, 'Ошибка', 'Нет файлов txt')
Local $sFile, $sData, $aData, $oBook, $oExcel = _Excel_Open(False)
While 1
	$sFile = FileFindNextFile($hSearch)
	If @error Then ExitLoop

	$sData = FileRead($sFile) ;Читаем файл
	$sData = StringReplace($sData, '.', ',') ;Меняем точки на запятые
	$aData = StringSplit($sData, @CRLF, 1 + 2) ;Делаем массив

	$oBook = _Excel_BookNew($oExcel) ;Новая книга
	_Excel_RangeWrite($oBook, 1, $aData) ;запись массива
	_Excel_BookSaveAs($oBook, @ScriptDir & '\' & $sFile & '.xls', $xlExcel8) ;сохранение как xls
	_Excel_BookClose($oBook, False) ;Закрытие
WEnd
_Excel_Close($oExcel)

Скрипт вечно сидит в цикле While и не может оттуда выйти без посторонней помощи. Причем он там сидит в независимости от того, если ли с ним в папке *.txt файлы или нет. Файлы *.xls не создаются.
 
A

Alofa

Гость
NiceScript, у вас Office-то какой?


Добавлено:
Сообщение автоматически объединено:

Скопируйте всю папку на рабочий стол и там попробуйте.
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
Alofa сказал(а):
NiceScript, у вас Office-то какой?


Добавлено:
Сообщение автоматически объединено:

Скопируйте всю папку на рабочий стол и там попробуйте.




Microsoft Office Excel 2003 (11.8342.8341) SP3

И папку на рабочий стол помещал, и файлы просто на рабочий стол размещал - запускал скрипт с вашим текстом, ничего не происходит.

Я тут хелп стал читать, а там пример
Код:
; ************************************************
; Пример 1 - Создает рабочую книгу Excel
; ************************************************
#include <Excel.au3>

$oExcel = _ExcelBookNew()
	If Not @error Then MsgBox(4096, "_ExcelBookNew | Пример 1", "Книга создана!")


Когда его выполняю, то пишется ошибка (в ваших скриптах никаких ошибок не выдает интерпретатор):
Код:
error: _ExcelBookNew(): undefined function.

может это быть связано?
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
NiceScript
Ответ #4
Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


С уважением, ваш Глобальный модератор.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
может это быть связано?
С тем, что пример в русской справке под старую версию AutoIt , начиная по-моему с 12 версии (может и раньше) изменилась UDF "Excel.au3" и стала не совместима с прежними версиями. Функция из Вашего примера в новой версии - "_Excel_BookNew()", смотрите примеры в англоязычной справке.
Код:
#include <Excel.au3>
#include <MsgBoxConstants.au3>

; Create application object
Local $oExcel = _Excel_Open()
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_BookOpen Example", "Error creating the Excel application object." & @CRLF & "@error = " & @error & ", @extended = " & @extended)

; *****************************************************************************
; Create a new workbook with only 2 worksheets
; *****************************************************************************
_Excel_BookNew($oExcel, 2)
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_BookNew Example 1", "Error creating new workbook." & @CRLF & "@error = " & @error & ", @extended = " & @extended)
MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_BookNew Example 1", "Workbook has been created successfully with only 2 worksheets.")
Если преобразовать Ваши файлы в формат csv , Вас устроит? Так можно обойтись вообще без UDF "Excel.au3"
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
ra4o сказал(а):
...
Если преобразовать Ваши файлы в формат csv , Вас устроит? Так можно обойтись вообще без UDF "Excel.au3"

Импорт *.csv файла в последующей программе рассматривает запятую, как разделитель и разносит целую и дробную часть в разные элементы списка.
Если же оставить точку, то считает это строкой. В общем - не устроит, но спасибо, что посмотрел!

Так же ваш пример из английского хелпа позволил создать файл в *.xls, значит в этом плане все нормально.
 
A

Alofa

Гость
NiceScript сказал(а):
... Microsoft Office Excel 2003 ...
Никогда не понимал этой привязанности к 2003-му, но это ладно.
У вас два варианта разрешения ситуации:
Обновите уже наконец Office, хотя бы до 2007.
В папку "Include" (директория установки Autoit) закиньте библиотеку "Excel_2003.au3" (из v3.3.8.1).
И далее пользуйтесь ей:
Код:
#include <File.au3>
#include <Excel_2003.au3>

Global $aFileList, $oExcel, $sText, $aText

$aFileList = _FileListToArray(@ScriptDir, '*.txt', $FLTA_FILES)
If @error Then Exit

For $i = 1 To $aFileList[0]
	$sText = FileRead(@ScriptDir & '\' & $aFileList[$i])
	If @error Then ContinueLoop
	$aText = StringRegExp($sText, '(\d+\.\d+).*', 3)
	If @error Then ContinueLoop
	For $j = 0 To UBound($aText) - 1
		$aText[$j] = StringReplace(Round($aText[$j], 9), '.', ',') ; Round() => округление до 9 символов после запятой
	Next
	$oExcel = _ExcelBookNew(0)
	If @error Then ContinueLoop
	_ExcelWriteArray($oExcel, 1, 1, $aText, 1)
	If Not @error Then _ExcelBookSaveAs($oExcel, @ScriptDir & '\' & StringTrimRight($aFileList[$i], 3) & 'xls', 'xls', 0, 1)
	_ExcelBookClose($oExcel, 0)
Next
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
Alofa сказал(а):
...
Никогда не понимал этой привязанности к 2003-му, но это ладно.
...

Воспринимайте это как рабочий инструмент, который удобнее последующих для конкретной работы.
Ваш второй вариант работает, за исключением следующих недоразумений.

Данные из *.txt
Код:
1.50051547761422 
6.57252030578093E-14 
-1.50051547761424

Превратятся в *.xls
Код:
1,500515478
6,572520306
1,500515478

А должны в *.xls
Код:
1,50051547761422
6,57252030578093E-14
-1,50051547761424

Если бы дело было в значащих цифрах, то я спокойно сделал бы Round(<>, 14), но тут дело с околонулевыми значениями. Есть вариант это исправить? В общем случае вы задачу решили, правда, она пока не пригодна для работы.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
NiceScript [?]
Скрипт вечно сидит в цикле While и не может оттуда выйти без посторонней помощи. Причем он там сидит в независимости от того, если ли с ним в папке *.txt файлы или нет.
Парни, подскажите, как такое может быть?
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
Alofa сказал(а):
NiceScript сказал(а):
... за исключением следующих недоразумений.
Мы так не договаривались :shok:

Ладно, ставлю задача решена. Спасибо огромное.
Переделаю формат вывода в *.txt файлы ({0:f14}), тогда и мантисс не будет.

Кстати, а если файлы *.txt будут следующего типа
Код:
0,606217782649107; 0,35; 
0,606217782649107; 0,35; 
0,862435565298214; 0,606217782649107;

тяжело ли их переделывать в *.xls, но уже не по одному столбику в файле, а столько, сколько содержится ';' в *.txt

inververs сказал(а):
NiceScript [?]
Скрипт вечно сидит в цикле While и не может оттуда выйти без посторонней помощи. Причем он там сидит в независимости от того, если ли с ним в папке *.txt файлы или нет.
Парни, подскажите, как такое может быть?

Мой конечный автомат твой тьюринг бумага заляпал в месте @error.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Ну понятно, между функцией и @error нельзя ничего вставлять.
 
Автор
N

NiceScript

Новичок
Сообщения
8
Репутация
0
Убрал, что тема решена, т.к. когда изменил формат вывода без мантисс, нашел более страшный глюк.

Код:
 0.00000
 4.09952
 1.50048
 0.00000
-1.50064
-4.09936
 0.00000
 4.09952
 1.50048
 0.00000
-1.50048
-4.09952
 0.00000

Получаем *.xls следующего содержания:
*округление до 5 поставил в Round.

Код:
0
4,09952
1,50048
0
1,50064
4,09936
0
4,09952
1,50048
0
1,50048
4,09952
0

На лицо преобразование отрицательных чисел в положительные.



Добавлено:
Сообщение автоматически объединено:

inververs сказал(а):
Ну понятно, между функцией и @error нельзя ничего вставлять.

А вы можете переделать ваш код под 2003 office?


Добавлено:
Сообщение автоматически объединено:

Всё, допилил сам, уж больно жалко было столько времени потратить впустую (особенно, когда формат вывода переделывал). Спасибо ребята за отзывчивость!
Вот крайний код.

Код:
#include <File.au3>
#include <Excel_2003.au3>

Global $aFileList, $oExcel, $sText, $aText

$aFileList = _FileListToArray(@ScriptDir, '*.txt', $FLTA_FILES)
If @error Then Exit

For $i = 1 To $aFileList[0]
    $sText = FileRead(@ScriptDir & '\' & $aFileList[$i])
    If @error Then ContinueLoop
    $aText = StringRegExp($sText, '(.\d+\.\d+).*', 3) ; тут точку добавил, чтобы знак "-" искался. Сцуко уже стал понимать ваш команды.
    If @error Then ContinueLoop
    For $j = 0 To UBound($aText) - 1
        $aText[$j] = StringReplace(Round($aText[$j], 5), '.', ',') ; Round() => округление до 9 символов после запятой
    Next
    $oExcel = _ExcelBookNew(0)
    If @error Then ContinueLoop
    _ExcelWriteArray($oExcel, 1, 1, $aText, 1)
    If Not @error Then _ExcelBookSaveAs($oExcel, @ScriptDir & '\' & StringTrimRight($aFileList[$i], 3) & 'xls', 'xls', 0, 1)
    _ExcelBookClose($oExcel, 0)
Next
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Ради спортивного интереса сделал средствами только офиса.
Только для одного файла, без всяких udf
Код:
$file = "c:\Users\1\Desktop\Новый текстовый документ.txt"
$xls = "c:\Users\1\Desktop\Новый текстовый документ.xls" ;2003
;$xls = "c:\Users\1\Desktop\Новый текстовый документ.xlsx" ;2007
$oExcel = ObjCreate("Excel.Application")
$oExcel.Visible = True
$oExcel.Workbooks.OpenText($file, Default, 1, Default, 1, False, True, False, False, False, False, False)
$vRange = $oExcel.ActiveSheet.Usedrange
$vRange.Replace(".", ",")
$oExcel.ActiveSheet.Columns("A").NumberFormat = "0,000000"
$oExcel.WorkBooks("Новый текстовый документ").SaveAs($xls,51)
$oExcel.Quit()
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Импорт *.csv файла в последующей программе рассматривает запятую, как разделитель и разносит целую и дробную часть в разные элементы списка.
Просто измените расширение файла из "txt" в "csv" (по умолчанию разделитель ";")
 
Верх