1C 7.7 + Etersoft Wine + PostgreSQL

Довольно часто требуется обеспечить интеграцию программы 1С с другими базами данных. Под Windows это легко запрограммировать с помощью ADO. А как быть, если 1C работает в среде Linux под Wine? ADO с Wine не очень-то стыкуется, к тому же теряется лицензионная чистота. Остается использовать UNIX-way. Например, задействовать демон incron, реагирующий на изменения файлов.

Предположим, нам нужно синхронизировать данные некоего справочника 1С. В процедуру модуля, запускаемую при сохранении записи, нужно добавить небольшой код, дублитрующий сохраняемые данные в XML-файл. В нашем случае данные передавались из 1С 7.7: Медицинские услуги.

Настраиваем демон incron так, чтобы он реагировал на изменения в нужном каталоге. Создаем файл /etc/incron.d/patients-to-psql:

/путь/к/базе/xml/ IN_MODIFY /etc/patients-to-psql.sh /путь/к/базе/xml/ $# $%


Т.е. в момент изменения файла (или создания) вызывается скрипт /etc/patients-to-psql.sh, которому передаются параметры: путь к файлу, имя файла, код события (например, IN_MODIFY).

Создаем скрипт, сохраняющий xml в базе данных:

#!/bin/bash

# Получаем имя файла без расширения
ID=$(echo "$2" | sed 's/\.[^\.]*$//')
# Получаем расширение
EXT=$(echo "$2" | sed 's/^.*\.//')
# id филиала
ID_FIL=0

# Запрос для добавления записи в БД 
INSERT_XML=$(echo "insert into patients values ($ID, '$(cat $1$2 | sed "s/'//g")', $ID_FIL)" | iconv -f cp1251 -t utf8 -c)
# Запрос для обновления записи в БД
UPDATE_XML=$(echo "update patients set xml = '$(cat $1$2 | sed "s/'//g")' where id = $ID and id_filial = $ID_FIL" | iconv -f cp1251 -t utf8 -c)
# Запрос на получение записи из БД
CHECK_SQL="select id from patients where id = $ID and $ID_FIL = id_filial"
# Команда PostgreSQL для выполнения запроса
PSQL="psql -U имя_пользователя -d имя_базы -h хост -t"

if [ $EXT != "xml" ] ; then exit 1 ; fi
if [ $3 != "IN_MODIFY" ] ; then exit 2 ; fi
    
# Если запись существует в БД - делаем UPDATE, иначе - INSERT
if [ -z $(echo "$CHECK_SQL" | $PSQL) ] ; then
         echo "$INSERT_XML" | $PSQL
else
         echo "$UPDATE_XML" | $PSQL
fi


Соответственно, необходимо внести изменения в конфигурацию 1С 7.7 и создать xml шаблон в /путь/к/базе/ExtForms/patient.xml:

<?xml version="1.0" encoding="UTF-8"?><patient_info name_1="%name_1%" name_2="%name_2%" name_3="%name_3%" id="%id%" birthday="%birthday%" address="%address%" passport_series="%passport_series%" passport_number="%passport_number%" passport_issue_date="%passport_issue_date%" passport_issued_by="%passport_issued_by%"/>


Редактируем процедуру «ПриЗаписи()»:




Процедура ПриЗаписи()                                                     
	Наименование=СокрЛП(Фамилия)+" "+Сред(Имя,1,1)+"."+Сред(Отчество,1,1);    
	Если флНового=1 Тогда  
		Если ПустоеЗначение(КодКарты)=0 Тогда
			Спр=СоздатьОбъект("Справочник.АмбулаторныеКарты");
			Если Спр.НайтиПоРеквизиту("КодКарты",КодКарты,1)=1 Тогда
				 Предупреждение("Карта с таким номером уже существует!");
				 СтатусВозврата(0);
			КонецЕсли;	
		КонецЕсли;	
	КонецЕсли;	
     КодКарты=Код;   
	
	// Экспорт данных о пациенте в базу на PostgreSQL
	/////////////////////////////////////////////////
	// При нажатии на кнопку OK в амбулаторной карте пациента происходит ее сохранение
	// в [медбаза]\xml\[номер карты].xml, этот файл скриптом отправляется в базу
	// Шаблон XML файла хранится в [медбаза]\ExtForms\patient.xml
	
	ПолноеИмяФайла = КаталогИБ() + "xml\" + СокрЛП(КодКарты) + ".xml"; 
		
 		XML = СоздатьОбъект("Текст");
 		XML.Открыть(КаталогИБ() + "ExtForms\patient.xml");
 		Data = XML.ПолучитьСтроку(1);

 		//Сообщить(Data);
                                          
 		с = СтрЗаменить(Data, "%name_1%",              СокрЛП(Фамилия));
 		с = СтрЗаменить(с,    "%name_2%",              СокрЛП(Имя));
 		с = СтрЗаменить(с,    "%name_3%",              СокрЛП(Отчество));
 		с = СтрЗаменить(с,    "%id%",                  СокрЛП(КодКарты));
 		с = СтрЗаменить(с,    "%birthday%",            ДатаР);
 		с = СтрЗаменить(с,    "%address%",             СокрЛП(АдресДомашний));
 		с = СтрЗаменить(с,    "%passport_series%",     СокрЛП(СерияПаспорта));
 		с = СтрЗаменить(с,    "%passport_number%",     СокрЛП(НомерПаспорта));
 		с = СтрЗаменить(с,    "%passport_issue_date%", ДатаВыдачи);
 		с = СтрЗаменить(с,    "%passport_issued_by%",  СокрЛП(КемВыдан));
 		
	    Текст = СоздатьОбъект("Текст"); 
		Текст.ДобавитьСтроку(с); 
		Попытка    
			Текст.Записать(ПолноеИмяФайла);
		Исключение           
			Сообщить("Не удалось сделать запись в базу данных (7).");
		КонецПопытки;	
   //мое конец
   
КонецПроцедуры


Теперь при создании новой амбулаторной карты, или при изменении, сформированные xml файлы окажутся в базе данных PostgreSQL.

Написано по большей части yababay.
  • +8
  • 01 ноября 2010, 19:48
  • Sergei_T

Комментарии (2)

RSS свернуть / развернуть
+
0
Фигасе ты тему раскрыл Аж 1С-овский код не поленился выложить и прокомментировать всё.

30% != «по большей части»
avatar

yababay

  • 02 ноября 2010, 01:51
+
0
Недаром 30 000 посещений за год !
avatar

Markony

  • 02 ноября 2010, 12:14

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.