Преобразование файлов 1CClientBankExchange в табличную форму

Лично мне периодически приходилось сталкиваться с обработкой данных не в табличной форме, а в "именованном формате" то есть когда каждый параметр пишется на отдельной строке в виде Параметр=Значение параметра причем файл имеет строго выраженную периодическую структуру и любой из параметров является необязательным. Порядок следования - произвольный.
Пример такого формата - стандартный формат 1С для общения с клиент-банками 1CClientBankExchange
На самом деле его можно даже средствами "малой механизации"(то есть чистый CMD-скрипт) преобразовать в табличную форму для дальнейшей обработки.
Привожу пример скрипта(кодировка Win1251):

@ECHO OFF CLS
COLOR 1E
CHCP 1251>NUL 2>&1

:: Папка с файлами для обработки. Полный путь в WIN1251!!!
SET "INPUT_DIR=D:\DATABASE"
:: Папка с выходными файлами. Полный путь в WIN1251!!!
:: Может совпадать с исходной папкой.
SET "OUTPUT_DIR=D:\DATABASE"
:: Папка для бэкапа входящих файлов. Полный путь в WIN1251!!!
:: Если она не указана то исходные файлы удалятся!!!
SET "BACKUP_DIR=D:\DATABASE\BACKUP"
:: Маска файлов для обработки
SET "FILE_MASK=to1c????.txt"

IF NOT EXIST "%INPUT_DIR%\" (ECHO Папка с файлами для обработки не найдена!&GOTO ERROR)
2>NUL DIR /B "%INPUT_DIR%\%FILE_MASK%"|1>NUL FIND /C /V ""||(ECHO Файлы для обработки не найдены!&GOTO ERROR)
IF NOT EXIST "%OUTPUT_DIR%" MD "%OUTPUT_DIR%"
IF NOT EXIST "%OUTPUT_DIR%" ECHO Не удалось создать папку для выходных файлов!&GOTO ERROR
IF NOT "%BACKUP_DIR%"=="" (
IF NOT EXIST "%BACKUP_DIR%" MD "%BACKUP_DIR%"
IF NOT EXIST "%BACKUP_DIR%" ECHO Не удалось создать папку для бэкапа файлов!&GOTO ERROR
)

ECHO Представляем системную дату в удобном виде:
ECHO wscript.ECHO YEAR(DATE) ^& RIGHT(0 ^& MONTH(DATE),2) ^& RIGHT(0 ^& DAY(DATE),2)>"%TEMP%\tmp.vbs"
FOR /F %%i IN ('cscript "%TEMP%\tmp.vbs" //Nologo') DO SET "TEKDATA=%%i"
IF EXIST "%TEMP%\tmp.vbs" DEL "%TEMP%\tmp.vbs"
ECHO %TEKDATA%

SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "usebackq" %%i IN (`DIR /B /A:-D "%INPUT_DIR%\%FILE_MASK%"`) DO (0<"%INPUT_DIR%\%%i" SET /P "LINE_1=") &IF /I "!LINE_1!"=="1CClientBankExchange" CALL :MAIN "%%i"
ENDLOCAL
EXIT

:MAIN
SET "FILE_NAME=%~1"
SET "NEWFILE_NAME=%TEKDATA%_%~1"
ECHO Выводим строку заголовков
1>"%OUTPUT_DIR%\%NEWFILE_NAME%" (ECHO 01-Номер^|02-Дата^|03-Сумма^|04-ДатаСписано^|05-Плательщик^|06-ПлательщикИНН^|07-ПлательщикКПП^|08-Плательщик1^|09-ПлательщикСчет^|10-ПлательщикРасчСчет^|11-ПлательщикБанк1^|12-ПлательщикБанк2^|13-ПлательщикБИК^|14-ПлательщикКорсчет^|15-ДатаПоступило^|16-Получатель^|17-ПолучательИНН^|18-ПолучательКПП^|19-Получатель1^|20-ПолучательСчет^|21-ПолучательРасчСчет^|22-ПолучательБанк1^|23-ПолучательБанк2^|24-ПолучательБИК^|25-ПолучательКорсчет^|26-ВидПлатежа^|27-ВидОплаты^|28-СтатусСоставителя^|29-ПоказательКБК^|30-ОКАТО^|31-ПоказательОснования^|32-ПоказательПериода^|33-ПоказательНомера^|34-ПоказательДаты^|35-ПоказательТипа^|36-СрокПлатежа^|37-Очередность^|38-НазначениеПлатежа^|39-Имя файла для приема^|)

SET "POINTER="
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "USEBACKQ TOKENS=1* DELIMS== " %%a in ("%INPUT_DIR%\%FILE_NAME%") DO (
IF "%%a"=="КонецДокумента" CALL :TOFILE&SET "POINTER=0"
IF !POINTER!==1 (IF NOT "%%~b"=="" (
IF /I "%%~a"=="Номер" SET "PP_1=%%~b"
IF /I "%%~a"=="Дата" SET "PP_2=%%~b"
IF /I "%%~a"=="Сумма" SET "PP_3=%%~b"
IF /I "%%~a"=="ДатаСписано" SET "PP_4=%%~b"
IF /I "%%~a"=="Плательщик" SET "PP_5=%%~b"
IF /I "%%~a"=="ПлательщикИНН" SET "PP_6=%%~b"
IF /I "%%~a"=="ПлательщикКПП" SET "PP_7=%%~b"
IF /I "%%~a"=="Плательщик1" SET "PP_8=%%~b"
IF /I "%%~a"=="ПлательщикСчет" SET "PP_9=%%~b"
IF /I "%%~a"=="ПлательщикРасчСчет" SET "PP_10=%%~b"
IF /I "%%~a"=="ПлательщикБанк1" SET "PP_11=%%~b"
IF /I "%%~a"=="ПлательщикБанк2" SET "PP_12=%%~b"
IF /I "%%~a"=="ПлательщикБИК" SET "PP_13=%%~b"
IF /I "%%~a"=="ПлательщикКорсчет" SET "PP_14=%%~b"
IF /I "%%~a"=="ДатаПоступило" SET "PP_15=%%~b"
IF /I "%%~a"=="Получатель" SET "PP_16=%%~b"
IF /I "%%~a"=="ПолучательИНН" SET "PP_17=%%~b"
IF /I "%%~a"=="ПолучательКПП" SET "PP_18=%%~b"
IF /I "%%~a"=="Получатель1" SET "PP_19=%%~b"
IF /I "%%~a"=="ПолучательСчет" SET "PP_20=%%~b"
IF /I "%%~a"=="ПолучательРасчСчет" SET "PP_21=%%~b"
IF /I "%%~a"=="ПолучательБанк1" SET "PP_22=%%~b"
IF /I "%%~a"=="ПолучательБанк2" SET "PP_23=%%~b"
IF /I "%%~a"=="ПолучательБИК" SET "PP_24=%%~b"
IF /I "%%~a"=="ПолучательКорсчет" SET "PP_25=%%~b"
IF /I "%%~a"=="ВидПлатежа" SET "PP_26=%%~b"
IF /I "%%~a"=="ВидОплаты" SET "PP_27=%%~b"
IF /I "%%~a"=="СтатусСоставителя" SET "PP_28=%%~b"
IF /I "%%~a"=="ПоказательКБК" SET "PP_29=%%~b"
IF /I "%%~a"=="ОКАТО" SET "PP_30=%%~b"
IF /I "%%~a"=="ПоказательОснования" SET "PP_31=%%~b"
IF /I "%%~a"=="ПоказательПериода" SET "PP_32=%%~b"
IF /I "%%~a"=="ПоказательНомера" SET "PP_33=%%~b"
IF /I "%%~a"=="ПоказательДаты" SET "PP_34=%%~b"
IF /I "%%~a"=="ПоказательТипа" SET "PP_35=%%~b"
IF /I "%%~a"=="СрокПлатежа" SET "PP_36=%%~b"
IF /I "%%~a"=="Очередность" SET "PP_37=%%~b"
IF /I "%%~a"=="НазначениеПлатежа" SET "PP_38=%%~b"
SET "PP_39=\\%COMPUTERNAME%@%INPUT_DIR%\%FILE_NAME%"
)
)
IF /I "%%a"=="СекцияДокумент" (SET "POINTER=1"&CALL :INIT)
)
ENDLOCAL
ECHO Формирование файла "%OUTPUT_DIR%\%NEWFILE_NAME%" формата текст с разделителями завершено!
IF NOT EXIST "%BACKUP_DIR%\%TEKDATA%" MD "%BACKUP_DIR%\%TEKDATA%"
IF NOT "%BACKUP_DIR%"=="" (MOVE /Y "%INPUT_DIR%\%FILE_NAME%" "%BACKUP_DIR%\%TEKDATA%") ELSE (DEL /Q /F "%INPUT_DIR%\%FILE_NAME%")
GOTO :EOF

:INIT
FOR /L %%z IN (1,1,39) DO SET "PP_%%z="
GOTO :EOF

:TOFILE
ECHO Вывод платежки N %PP_1% в файл "%OUTPUT_DIR%\%NEWFILE_NAME%"
FOR /L %%z IN (1,1,39) DO (
1>>"%OUTPUT_DIR%\%NEWFILE_NAME%" SET /P "=!PP_%%z!^|" >"%OUTPUT_DIR%\%NEWFILE_NAME%" (ECHO.)
GOTO :EOF

:ERROR
PAUSE
COLOR

При этом получим на выходе текстовый файл с разделителем "|" между полями.
Первой строкой будет выведена строка заголовков:
01-Номер|
02-Дата|
03-Сумма|
04-ДатаСписано|
05-Плательщик|
06-ПлательщикИНН|
07-ПлательщикКПП|
08-Плательщик1|
09-ПлательщикСчет|
10-ПлательщикРасчСчет|
11-ПлательщикБанк1|
12-ПлательщикБанк2|
13-ПлательщикБИК|
14-ПлательщикКорсчет|
15-ДатаПоступило|
16-Получатель|
17-ПолучательИНН|
18-ПолучательКПП|
19-Получатель1|
20-ПолучательСчет|
21-ПолучательРасчСчет|
22-ПолучательБанк1|
23-ПолучательБанк2|
24-ПолучательБИК|
25-ПолучательКорсчет|
26-ВидПлатежа|
27-ВидОплаты|
28-СтатусСоставителя|
29-ПоказательКБК|
30-ОКАТО|
31-ПоказательОснования|
32-ПоказательПериода|
33-ПоказательНомера|
34-ПоказательДаты|
35-ПоказательТипа|
36-СрокПлатежа|
37-Очередность|
38-НазначениеПлатежа|
39-Имя файла для приема|

Само-собой не в приведенном виде - а в виде одной строки ;)

Файлы: 
ВложениеРазмер
Файл preobrazovanie_faylov_1cclientbankexchange_v_tablicu.7z1.98 КБ

Похожие материалы по этой теме на сайте

Содержимое
Интерпретатор CMD - вывод переменных со спецсимволами на экран и в файл

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

Скрипты для CMD

Скрипты выполняемые интерпретатором CMD.EXE - стандартной консольной оболочкой для Win2000/WinXP/Vista/Seven/Win8/Win2000 Server/Win2003/Win2008.

Страховое копирование по списку

Относительно простой вариант резервного копирования по списку файлов/папок с учетом типа резервной копии и количества хранимых копий по типам. Классические типы: дневная-недельная-месячная-годовая копии. Кодировка скрипта CP866....

Чтение данных из реестра в переменную окружения

Продвинутый кросплатформенный модуль для встраивания в скрипты, позволяющий в удобной форме получать данные из реестра для дальнейшего использования(как всегда - кодировка скрипта CP866):

Выключение компьютеров в домене по списку
Монолитный скрипт выключения компьютеров в домене по списку:
@ECHO OFF
SET "BEGIN_MARKER=:ENDFILE1"
SET "END_MARKER=:ENDFILE2"
Логофф сессий отключенных пользователей на терминальном сервере

Убить все отключенные сессии:

@ECHO OFF
FOR /F "USEBACKQ TOKENS=2 DELIMS= " %%a IN (`quser^|findstr /b /v "^>"^|findstr /i /v " ID "^|findstr /v /i "rdp-tcp"`) DO logoff %%~a
EXIT 0
Настраиваемые представления журналов Windows
Через журналы Windows можно помотреть много чего интересного.
Но есть нюанс - самое интересное обычно сидит в расширенных атрибутах и фильтр по ним через GUI создать невозможно.
Поддержка папок для сканирования

Часто в офисе присутствуют сетевые устройства сканирования, которые поддерживают сканирование в сетевую папку. Все бы было хорошо если бы для этих устройств