Что нового

Автоматизация создания таблицы в Exel из текстовых файлов

ab_99

Новичок
Сообщения
5
Репутация
0
Здраствуйте!
Помогите с написанием скрипта для редактирования текстовых файлов игры Казаки.

Версия AutoIt: 3.3.7.14

Описание:
В папке около 500 файлов в текстовом формате (расширение .md)
необходимо загрузить в таблицу EXEL все *.md файлы (или по списку файлов из list.txt)
каждый файл записывается в отдельный столбец, первая ячейка столбца содержит имя файла.
одна ячейка содержит одну строку текста (до символа конца строки)
после заполнения 256 столбцов открыть новый лист
после редактирования таблицы обратно сохранить в файлы выделенные столбцы (по имени из первой ячейки)

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

axlwor

Скриптер
Сообщения
657
Репутация
147
вручную такое срабатывает? excel любит заменять многие символы :'(
 
Автор
A

ab_99

Новичок
Сообщения
5
Репутация
0
Срабатывает, символы все печатные, пока встречался только перенос на разные столбцы, скорее всего из-за TAB.
Дальше идет сортировка строк по имени команды (первое слово строки), пока все распознает.
 

sngr

AutoIT Гуру
Сообщения
985
Репутация
392
Замени в исходном файле табы на пробелы.
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
ab_99
Вот кое-что.
Не универсально (в некоторых случаях не работает)
Нет многих проверок на ошибки при различных ситуациях.
С файлом List.txt из 6 файлов, вроде работает. Первый лист 3 столбца,
затем 2-й три столбца.
Код:
#include <file.au3>
#include <Array.au3>
#include <Excel.au3>
$sFileXLSPath = @ScriptDir & "\AutoIt_md.xls"
$oExcel = _ExcelBookOpen($sFileXLSPath);открываем книгу Excel
If @error Then;если не получилось, сообщить и выйти
	MsgBox(16, "Ошибка!", "Ошибка")
	Exit
EndIf
_ExcelSheetActivate($oExcel, 1);активируем первый лист книги
Dim $aFileList
_FileReadToArray (@ScriptDir&"\List.txt", $aFileList);читаем в массив список файлов
$Num = UBound($aFileList)-1;сколько файлов для обработки лежит в массиве
Dim $aFile

For $i = 1 To $Num ;пишем данные в 1-й активный лист
	_FileReadToArray ($aFileList[$i], $aFile);читаем содержимое файла md в массив	
	_ExcelWriteCell($oExcel, $aFileList[$i], 1, $i);пишем имя файла в книгу
	_ExcelWriteArray($oExcel, 2, $i, $aFile, 1);пишем содержимое файла в книгу
	_ArrayDelete($aFileList,1);удаляем из массива имя файла, что уже записали	
	If $i = 3 Then ExitLoop ;ограничение записи на листе в 3 столбца, т.е. выходим		
	Next
	
_ExcelRowDelete($oExcel, 2, 1);удаляем 2-ю строку таблицы 1-го листа
$Num = UBound($aFileList)-1;получаем размер массива новый
_ExcelSheetActivate($oExcel, 2);активируем 2-й лист

For $i = 1 To $Num ;пишем данные во 2-й активный лист
	_FileReadToArray ($aFileList[$i], $aFile)	
	_ExcelWriteCell($oExcel, $aFileList[$i], 1, $i)	
	_ExcelWriteArray($oExcel, 2, $i, $aFile, 1)	
Next

_ExcelRowDelete($oExcel, 2, 1);удаляем 2-ю строку таблицы 2-го листа
MsgBox(64, "Инфо", "Готово")
_ExcelBookClose($oExcel, 1, 0);закрываем книгу с сохранением
 
Автор
A

ab_99

Новичок
Сообщения
5
Репутация
0
Yuriy
Большое Спасибо!
Скрипт работает, копирует. Разбивка на циклы записи отдельных листов даже лучше, смогу делать разбивку по категориям, написав несколько листингов для каждого листа.
Да, Ехеl заменяет TAB на квадратик, может это как-то связано с кодировкой? (н-р, третий столбик после строки начинающейся на EX_SHOTS2). Поганяю, может еще выловлю какие символы. Можно будет добавить замену символа перед вставкой в ячейку?

Теперь бы еще сохранять обратно в текстовый файл.

Отдельное спасибо за комментарий, видел такой только в учебнике. :beer:
 
Автор
A

ab_99

Новичок
Сообщения
5
Репутация
0
Нашел нестабильность в работе. :'( Не всегда сохраняет книгу, т.е. на экране показывает выполнение, но после сообщения "инфо" закрывается книга без сохранения. При загрузке книга чистая, происходит не всегда, закономерности не обнаружил.

После добавления в список еще несколько файлов, стабильно не записыватся файл ARSENAL.MD на первом листе, который в предыдущем списке заносился в таблицу, вместо него пишет другой файл. Иногда на первом листе только одна запись, см.прилож.
Может нужно очищать переменные и книгу Exel? Хотя после перезагрузки компа результат такой же.

Просьба, добавить сохранение обработанных результатов в файлы, и для контроля сохранять листинг обработанных файлов.

В приложении дополненный набор файлов, при котором срабатывает ошибка.
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Предварительно выкладываю другой вариант.
Если он более подходящ, тогда будем наращивать.
Вся логика работы скрипта в комментариях.
Код:
#include <Array.au3>
#Include <File.au3>
#include <Excel.au3>
;########################################################################
;в этом блоке содаем файл-лист, узнаем кол-во файлов md
;узнаем необходимое количество листов в книге Excel для записи
$PathFileList = @ScriptDir&"\List.txt" ;путь к файлу List.txt
$searchMD = FileFindFirstFile(@ScriptDir&"\*.md");путь к файлам md

If $searchMD = -1 Then ;если нет md файлов, тогда
    MsgBox(16, "Ошибка", "Файлы md не найдены");сообщить 
    Exit;и выйти
EndIf

$fileList = FileOpen($PathFileList, 10);открываем файл List.txt для записи, если отсутствует, - создать
If $fileList = -1 Then
    MsgBox(16, "Ошибка", "Не удалось создать или открыть файл List.txt.")
    Exit
EndIf
$n=0;счетчик фкол-ва файлов md
While 1;ищем в цикле все файлы md
    $fileMD = FileFindNextFile($searchMD) 
    If @error Then ExitLoop;завершить цикл, т.к. все файлы найдены
	FileWriteLine($fileList, $fileMD & @CRLF);и пишем их имена в файл-лист
	$n=$n+1
WEnd
FileClose($searchMD)
FileClose($fileList)

MsgBox(64, "Инфо", "Всего файлов "&$n)
$numColumn = 5;лимит столбцов на один лист книги (можно 255 поставить)
$numList = 1;изначально кол-во листов для записи в книге - 1
If $n > $numColumn Then ;если файлов больше 5, тогда
	$numList = Ceiling($n/$numColumn);узнаем сколько в книге листов для записи необходимо	
	MsgBox(64, "Инфо", "Требуется листов книги " & $numList)
EndIf
;#############################################################################
;в этом блоке пытаемся открыть книгу Excel и активировать Лист №1
$sFileXLSPath = @ScriptDir & "\AutoIt_md.xls"
$oExcel = _ExcelBookOpen($sFileXLSPath);открываем книгу Excel
If @error Then;если не получилось, сообщить и выйти
	MsgBox(16, "Ошибка!", "Ошибка")
	Exit
EndIf
$aNumList = _ExcelSheetList($oExcel);узнаем сколько есть листов в книге
$var1 = UBound($aNumList)-1
MsgBox(64, "Кол-во листов", "В книге всего листов "& $var1)
If $var1 < $numList Then;если листов, меньше, чем надо, тогда
	$NewNumList = $numList - $var1;узнаем сколько еще надо
	_ExcelSheetActivate($oExcel, $var1)
	$z=0
	For $i=1 To $NewNumList;и создадим их		
		_ExcelSheetAddNew($oExcel)
		_ExcelSheetMove($oExcel, $var1+$i, $var1+$z, True)		
		_ExcelSheetActivate($oExcel, $var1+$i)
		$z=$z+1
	Next
EndIf
_ExcelSheetActivate($oExcel, 1);активируем первый лист книги
;#############################################################################
;в этом блоке читаем созданный ранее файл-лист в массив (имена файлов MD)
Dim $aFileList;общий массив имен файлов
Dim $aFileMD;массив содержимого файла MD
Dim $aListMD[1];массив имен файлов для записи на 1 лист
If Not _FileReadToArray($PathFileList, $aFileList) Then
    MsgBox (16,"Ошибка","Не удалось прочитать файл List.txt в массив")
    Exit
EndIf
;##############################################################################
$x=0;счетчик порций лимита столбцов на лист
$y=1;счетчик листов книги
For $i=1 To $n Step $numColumn ;с первого по пследний файл с шагом кол-ва столбцов на лист
	MsgBox(64, "Инфо", "Пишем столбцы, начиная с файла № " & $i)
	For $j=$i To $n	;с номера файла следующего листа		
		_ArrayAdd($aListMD,$aFileList[$j]);формируем в массиве порцию стлобцов для 1-го листа		
		$x=$x+1
		ExcelWrite($x);вызываем функцию записи в Excel
		If $x=$numColumn Then ;если достигли лимита кол-ва столбцов на 1 лист, тогда			
			$y=$y+1;получаем номер следующего листа
			_ExcelSheetActivate($oExcel, $y);и активируем следующий лист книги
			$x=0;обнуляем счетчик кол-ва столбцов на 1 лист
			Dim $aListMD[1];очищаем массив
			ExitLoop
		EndIf		
	Next		
Next

Func ExcelWrite($x)	
	_ExcelWriteCell($oExcel, $aListMD[$x], 1, $x);пишем имя файла
	_FileReadToArray ($aListMD[$x], $aFileMD);читаем содержимое файлов
	_ExcelWriteArray($oExcel, 2, $x, $aFileMD, 1);пишем содержимое файла	
EndFunc

For $i = 1 To $numList
	_ExcelSheetActivate($oExcel, $i)
	_ExcelRowDelete($oExcel, 2, 1);удаляем 2-ю строку таблицы текущего листа
Next

MsgBox(64, "Инфо", "Готово")
_ExcelBookClose($oExcel, 1, 0);закрываем книгу с сохранением
 
Автор
A

ab_99

Новичок
Сообщения
5
Репутация
0
Yuriy
Большое спасибо!
Этот вариант более подходящий. :ok:
Проверил на реальной папке, 665 файлов, 4 листа по 200, время выполнения 1ч10м. Страшно представить сколько бы пришлось вручную копировать. :shok:
В принципе можно в рабочую папку копировать порциями нужное к-во файлов, и формировать таблицы по категориям.
Сейчас важнее, чтобы файлы записывались после редактирования, желательно выборочные столбцы, иначе он и сохранять будет больше часа. Резерв по скорости имеется?
 
Верх