Чтение данных в 1С из базы данных Access через ADODB с фильтром по датам

Пришлось загружать данные о проходах с устройств Anviz, которые штатная программа СКУД CrossChex хранит в базе Access.

Все было хорошо, но возникла проблема с датами. Немного помогла статья про даты в Access.

В итоге в консоли запросов Access протестировал строку отбора вида:

SELECT CheckTime, CheckType, UserID, LogID FROM CheckInOut
WHERE     CheckTime > #28/3/2024 23:59:59#
	ORDER BY CheckTime, UserID
	

Работает правильно:

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

Обработка по чтению данных из Access на управляемых формах выглядит так:

Строка подключения имеет вид (с указанием имени файла):

Provider=Microsoft.Jet.OLEDB.4.0; Data Source="m:\fixin\Work\2024 Энвиз Клиент\CrossChex.mdb";

На некоторых версиях Windows нужно использовать другую строку:

Provider=Microsoft.ACE.OLEDB.12.0; Data Source="m:\fixin\Work\2024 Энвиз Клиент\CrossChex.mdb";

Возможно, понадобится установка Microsoft Access Database Engine 2016 Redistributable, если Access не установлен на компьютере.

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

Код обработки:


&НаСервере
Функция ПрочитатьДанныеНаСервере()
	// Вставить содержимое обработчика. 
	ТЗ = AnvizDB_ПрочитатьSQL(ВыбДата1, ВыбДата2, СтрокаПодключения);     
	Если ТЗ = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	ТабДок = ПечатьТЗ(ТЗ);
	Возврат ТабДок;
КонецФункции

Функция ПечатьТЗ(ТЗ)      
	ТабДок = Новый ТабличныйДокумент();
	ПострПечать = Новый ПостроительОтчета;
    ПострПечать.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗ);
    //ПострПечать.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.Интерфейс);
    ПострПечать.Выполнить();
    Для каждого Колонка Из ПострПечать.ВыбранныеПоля Цикл
        Колонка.Представление = ТЗ.Колонки[Колонка.Имя].Заголовок;
    КонецЦикла; 
    ПострПечать.Вывести(ТабДок); 
	Возврат ТабДок;
КонецФункции

&НаКлиенте
Процедура ПрочитатьДанные(Команда)
	ТабДок = ПрочитатьДанныеНаСервере();
	Если ТабДок <> Неопределено Тогда
		ТабДок.Показать();
	КонецЕсли;
КонецПроцедуры



Функция AnvizDB_ПрочитатьSQL(Дата1, Дата2, СтрокаПодключения) Экспорт
	SQLConnection = Новый COMОбъект("ADODB.Connection");
	ConnectString = СтрокаПодключения;
    SQLConnection.ConnectionString = ConnectString;
	
	
	//Подключаемся к базе данных 
    Try
        SQLConnection.Open();        
    Except 
        Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
        SQLConnection = Неопределено;
		Возврат Неопределено;
	EndTry;
	
	Команда = Новый COMОбъект("ADODB.Command");
	Команда.NamedParameters = True;
	Команда.CommandTimeOut = 1500000;
	Команда.CommandType =1;
	Команда.ActiveConnection = SQLConnection;
	
	//FOR ACCESS                                              
	ФорматДаты = "ДФ='MM/dd/yyyy HH:mm:ss'";
	Команда.CommandText =
	"SELECT CheckTime, CheckType, UserID, LogID FROM CheckInOut
	|WHERE     CheckTime BETWEEN #"+Формат(НачалоДня(Дата1),ФорматДаты)+"#
	|  and #"+Формат(КонецДня(Дата2),ФорматДаты)+"# ORDER BY CheckTime, UserID
	|";

	//FOR SQL
	//"SELECT CheckTime, CheckType, UserID, LogID FROM CheckInOut
	//|WHERE     CheckTime BETWEEN convert(datetime, '"+Формат(НачалоДня(Дата1),"ДФ='yyyy-MM-dd HH:mm:ss'")+"', 20) 
	//|  and convert(datetime, '"+Формат(КонецДня(Дата2),"ДФ='yyyy-MM-dd HH:mm:ss'")+"', 20) ORDER BY CheckTime, UserID
	//|";
						 

	
	RS = Новый COMОбъект("ADODB.Recordset");
	RS = Команда.Execute();
	
	ТЗ = Новый ТаблицаЗначений();
	ТЗ.Колонки.Добавить("Date");
	ТЗ.Колонки.Добавить("Time");
	ТЗ.Колонки.Добавить("PersonID");
	ТЗ.Колонки.Добавить("Stat");
	ТЗ.Колонки.Добавить("Point");
	ТЗ.Колонки.Добавить("Serial");
	
	СтатусВнутри = "0";
	СтатусСнаружи = "1";

	
	ВсегоЗаписей = 0;
	Сч = 0;
	Пока Не RS.Eof Цикл
		Стр = ТЗ.Добавить();
		Стр.Time = RS.Fields("CheckTime").Value;
		Стр.Date = НачалоДня(Стр.Time);
		Стр.PersonID = СокрЛП(RS.Fields("Userid").Value);
		Стр.Point = RS.Fields("LogID").Value;
		ТипПрохода = RS.Fields("CheckType").Value;
		

		Если ТипПрохода = "I" Тогда
			Стр.Stat = СтатусВнутри;
		ИначеЕсли ТипПрохода = "O" ИЛИ ТипПрохода = "0" Тогда
			Стр.Stat = СтатусСнаружи;
		КонецЕсли;
		Rs.MoveNext();
		#Если Клиент Тогда
			Если Сч % 10 Тогда 
				Состояние("Подождите идет получения внешних данных ..." + Сч );
				Сч = Сч + 1;
			КонецЕсли;
		#КонецЕсли
	КонецЦикла;

	Возврат ТЗ;

КонецФункции

Здесь все работает в файловой базе, поэтому я не делал сложных манипуляций с данными клиента и сервера. В рабочей базе тоже буду рассчитывать, что папка базы будет доступна с сервера.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *