Пример позволяет получать информацию по сотрудникам в заданных отделах и по нахождению на рабочем месте.
Обработка тестировалась на последней версии 1С (8.3.10.2561) и Win Server 2012 R2, использует только стандартные возможности платформы 1С + драйвер для СУБД MySQL.
Обработка содержит функции получения данных из СКУД Сигур (бывш. Сфинкс) хранящиеся в MySQL.
Пример позволяет получать информацию по сотрудникам в заданных отделах и по нахождению на рабочем месте.
Обработка тестировалась на версии 1с (8.3.10.2561) и Win Server 2012 R2, использует только стандартные возможности платформы 1с + драйвер для СУБД MySQL. Создавалась для самописной конфигурации.
Внимание, если вам интересно получать информацию по номерам карточек отличных от стандарта Wiegand-26 (код карты вида XXX,YYYYY) — допишите процедуру "РасшифроватьКарту(Код)", на вход она получает HEX значение из БД. Если вам не интересна информация по номерам карт, то на остальном функционале это никак не отразиться.
Переменные
Обработка содержит публичные переменные/реквизиты:
ВремяДома (Целое число [2]), Limit (Строка [10]), Табель (Строка [100])
Их описание дано в функции "Конструктор"
Приватные переменные:
Connection — COM Объект ADODB.Connection
Recordset — COM Объект ADODB.Recordset
Примеры использования:
Примеры использования
// // // // // // // // // // // // // // // // // // // // //
// Проверка соединения с БД
Сигур = Обработки.Сигур.Создать();
Если Соединение.Конструктор("MySQL ODBC 5.3 ANSI Driver")
И Соединение.Деструктор() Тогда
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "Успех!";
Сообщение.Сообщить();
КонецЕсли;
// // // // // // // // // // // // // // // // // // // // //
// Получение информации о сотрудниках
Сигур = Обработки.Сигур.Создать();
Сигур.Конструктор(Драйвер);
ТЗ = Соединение.ПолучитьСотрудников("Gebau", "1");
Сигур.Деструктор();
// // // // // // // // // // // // // // // // // // // // //
// Получение отладочной информации по посещаемости
Сигур = Обработки.Сигур.Создать();
Сигур.Конструктор(Драйвер, , , , , , Структура);
мДверей = Новый Массив;
мДверей.Добавить("Проходная (вертушка)");
мДверей.Добавить("Ворота (машины)");
Структура = Соединение.ПолучитьПосещаемость( Период.ДатаНачала,
Период.ДатаОкончания,
мДверей,
Сотрудник,
Истина);
ТабДок = Структура.ТабДок;
Сигур.Деструктор();
// // // // // // // // // // // // // // // // // // // // //
// Получение таблицы значений из произвольного запроса к БД
Сигур = Обработки.Сигур.Создать();
Сигур.Конструктор(Драйвер);
ТЗ = ВыполнитьЗапрос("SELECT * FROM `tc-db-main`.personal LIMIT 100");
Сигур.Деструктор();
Конструктор и деструктор
Использование обработки всегда должно начинаться с вызова конструктора!
...
Сигур = Обработки.Сигур.Создать();
Если Не Сигур.Конструктор(Драйвер) Тогда Возврат КонецЕсли;
...
Сигур.Деструктор();
...
Листинг конструктора и деструктора
#Область Конструктор_и_деструктор
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// КОНСТРУКТОР
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Самая первая функция, которую необходимо вызвать после
// инициализации обработки.
//
// Функция возвращает булево:
// Истина - Успешно установлено подключение к БД.
// Ложь - В случае неудачи, также будет выведено
// СообщениеПользователю с описанием ошибки.
//
// Параметры:
// Драйвер - [обязательный](строка)
// параметром передается название драйвера,
// необходимого для подключения к MySQL.
// На Win Server 2012 задается тут:
// Панель управления -> Все элементы панели управления
// -> Администрирование -> Источники данных ODBC (32/64-разрядная версия)
// -> Драйверы
// Пример: "MySQL ODBC 5.3 ANSI Driver"
// Сервер - [необязательный](строка)
// Адрес сервера для подключения к БД.
// Пример: "127.0.0.1"
// Порт - [необязательный](строка или число)
// Номер порта для подключения к БД
// Пример: "3305"
// База - [необязательный](строка)
// Имя БД в MySql Sigur
// Пример: "mysql"
// Пользователь - [необязательный](строка)
// Имя пользователя для подключения к БД
// Пример: "root"
// Пароль - [необязательный](строка)
// Пароль пользователя, по умолчанию без пароля.
// Пример: "password"
// Параметры - [необязательный](структура)
// Если передать структуру содержающую свойства с
// именами как у глобальных переменных (реквизитов),
// то они заменяться значениями из структуры.
// В будующем их можно заменить напрямую, если необходимо.
// Пример: Новый Структура("ВремяДома", 6)
Функция Конструктор( Знач Драйвер,
Знач Сервер = "127.0.0.1",
Знач Порт = "3305",
Знач База = "mysql",
Знач Пользователь = "root",
Знач Пароль = "",
Знач Параметры = Неопределено) Экспорт
// Смотрю, были ли переданы дополнительные параметры
// для заполнения публичных переменных
Если Параметры = Неопределено Тогда Параметры = Новый Структура КонецЕсли;
// Ограничение для выборок из BD, нужно для подстраховки, чтоб окончательно не
// подвесить 1с и MySql
Limit = ?(Параметры.Свойство("Limit"), Параметры.Limit, "100000");
// Константа для расчета рабочего времени (в часах)
// При отсутсвии использования карточки в течении
// этого времени после "Выхода" - считается,
// что человек ушел домой.
ВремяДома = ?(Параметры.Свойство("ВремяДома"), Параметры.ВремяДома, 5);
// Названия поля для связи/соответсвия справочника Сотрудников с полем "Табель" Сигур'а
// Нужно если в дополнении к имени сотрудника из сигура, нужно еще получать и ссылку на
// справочник "Сотрудники".
Табель = ?(Параметры.Свойство("Табель"), Параметры.Табель, "Код");
// Устанавливаю строку подключения
СтрокаПодключения = СтрШаблон("DRIVER={%1};SERVER=%2;PORT=%3;DATABASE=%4;uid=%5;pwd=%6;",
Драйвер, Сервер, Порт, База, Пользователь, Пароль);
// Подключаюсь к БД
Возврат ПодключитьБД(СтрокаПодключения);
КонецФункции // Конструктор()
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// ДЕСТРУКТОР
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Функция, которой, по хорошему, надо завершать
// жизненный цикл обработки.
//
// Функция возвращает булево:
// Истина - Успешно отключено от БД.
// Ложь - В случае неудачи, также будет выведено
// СообщениеПользователю с описанием ошибки.
Функция Деструктор() Экспорт
// Отключаюсь от БД
Возврат ОтключитьБД();
КонецФункции // Деструктор()
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
#КонецОбласти
#Область Подключить_и_отключить_базу_данных
Функция ПодключитьБД(Знач СтрокаПодключения)
Попытка
Connection = Новый COMОбъект("ADODB.Connection");
Recordset = Новый COMОбъект("ADODB.Recordset");
Connection.Open(СтрокаПодключения);
Возврат Истина;
Исключение
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = СтрШаблон("Во время подключения к бд произошла ошибка.
|Строка подключения: %1
|Описание ошибки: %2",
СтрокаПодключения,
ОписаниеОшибки());
Сообщение.Сообщить();
Возврат Ложь;
КонецПопытки;
КонецФункции // ПодключитьБД()
Функция ОтключитьБД()
Попытка
Connection.Close();
Connection = Неопределено;
Recordset = Неопределено;
Возврат Истина;
Исключение
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "Во время отключения от бд произошла ошибка.
|Описание ошибки:" + ОписаниеОшибки();
Сообщение.Сообщить();
Возврат Ложь;
КонецПопытки;
КонецФункции // ОтключитьБД()
Функция ПроверитьПодключение()
Подключение = ТипЗнч(Recordset) = Тип("COMОбъект") И ТипЗнч(Connection) = Тип("COMОбъект");
Если Не Подключение Тогда
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "Перед вызовом методов объекта вначале запустите конструктор!";
Сообщение.Сообщить();
КонецЕсли;
Возврат Подключение;
КонецФункции // ПроверитьПодключение()
#КонецОбласти
Основные функции:
ВыполнитьЗапрос()
ПолучитьСотрудников()
ПолучитьПосещаемость()
Листинг основных функций
#Область Запросы
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// ВЫПОЛНИТЬ ПРОИЗВОЛЬНЫЙ ЗАПРОС
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Функция позволяющая выполнить произвольный запрос к БД Сигур.
// Ввозвращает таблицу значений с результатами запроса.
//
// Параметры:
// ТекстЗапроса - [обязательный](строка)
// параметром передается текст запроса к БД.
// Пример: "SELECT * FROM `tc-db-main`.personal LIMIT 100"
Функция ВыполнитьЗапрос(Знач ТекстЗапроса) Экспорт
Recordset.Open(ТекстЗапроса, Connection, 1);
ТЗ = НаборЗаписейВТаблицу();
Возврат ТЗ;
КонецФункции // ВыполнитьЗапрос()
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Получить сотрудников
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Получить список всех сотрудников и сопутстсвующее описание
//
// Функция возвращает таблицу значений с информацией по сотрудникам.
//
// Параметры:
// Отдел - [необязательный](строка)
// параметром передается название отдела,
// можно передать отделы с разделителем ","
// пустая строка - все отделы
// Пример: "IT,Склад,Охрана"
// Уволенные - [необязательный](строка или число)
// 0 - все,
// 1 - действующие,
// 2 - уволенные
// Пример: "0"
// сГруппами - [необязательный](булево)
// Истина - оставить группы/отделы,
// Ложь - исключить группы/отделы,
// Пример: Ложь
Функция ПолучитьСотрудников( Знач Отдел = "",
Знач Уволенные = "1",
Знач сГруппами = Ложь) Экспорт
Если Не ПроверитьПодключение() Тогда
Возврат Неопределено;
КонецЕсли;
// На всякий кастую входные параметры
Отдел = Строка(Отдел); Уволенные = Строка(Уволенные);
ТекстЗапроса = "
|# ##### ##### ##### ##### #####
|# ЗАПРОС СОТРУДНИКОВ
|# ##### ##### ##### ##### #####
|SELECT
| P.ID AS ID, # ID
| P.PARENT_ID AS PARENT_ID, # PARENT_ID
| IF(P.TYPE=1,
| 'Отдел',
| 'Работник') AS TYPE, # Отдел (DEP) / Работник (EMP)
| P.NAME AS NAME, # Имя
| P.DESCRIPTION AS DESCRIPTION, # Описание
| P.POS AS POS, # Должность / Модель
| P.TABID AS TABID, # Табельный номер
| IF(P.STATUS=1,
| 'Работает',
| 'Удален') AS STATUS, # Работает / Удален
| P.CREATEDTIME AS CREATEDTIME, # Время создания
| P.FIREDTIME AS FIREDTIME, # Время удаления (увольнения)
| HEX(P.CODEKEY) AS CODEKEY # Код карты в HEX
|FROM
| `tc-db-main`.personal AS P
|WHERE
| IF("+Уволенные+" = '1', STATUS = 1, IF(@fired = '2', STATUS = 2, TRUE))
| OR P.TYPE = 1
|LIMIT "+Limit+"
|";
Recordset.Open(ТекстЗапроса, Connection, 1);
ТЗ = НаборЗаписейВТаблицу();
// Если нужны только заданные отделы и их предки,
// Возвращает массив "Отделы" содержащий строки с ID подразделений
ЕСЛИ Отдел <> "" ТОГДА
Отделы = Новый Массив;
Для Каждого Строка Из СтрРазделить(Отдел, ",", Ложь) Цикл
Строки = ТЗ.НайтиСтроки(Новый Структура("NAME,TYPE", СокрЛП(Строка), "Отдел"));
Отделы = КонкатенацияМассивов(Новый Структура("Отделы,Строки", Отделы, Строки), Истина);
КонецЦикла; // Для Каждого Строка Из СтрРазделить(Отдел, "," Ложь)
Было = 0;
// Получаю все вложенные отделы
Пока Было < Отделы.Количество() Цикл
Было = Отделы.Количество();
Для Каждого Строка Из Отделы Цикл
Строки = ТЗ.НайтиСтроки(Новый Структура("PARENT_ID,TYPE", Строка.ID, "Отдел"));
Отделы = КонкатенацияМассивов(Новый Структура("Отделы,Строки", Отделы, Строки), Истина);
КонецЦикла;
КонецЦикла; // ПОКА Было < Отделы.Количество()
Для Счетчик = 0 По Отделы.ВГраница() Цикл
Отделы.Установить(Счетчик, Отделы[Счетчик].ID);
КонецЦикла;
КОНЕЦЕСЛИ; // ЕСЛИ Отдел ""
ТЗ.Колонки.Вставить(0, "Сотрудник");
// Перебираю все строки ТЗ
мНаУдаление = Новый Массив;
ДЛЯ КАЖДОГО Строка ИЗ ТЗ ЦИКЛ
// Выкидываю строки содержащие описание подразделений
// или не входящие в заданные отделы
Если (Не сГруппами
И Строка.TYPE = "Отдел")
Или (Отдел ""
И Отделы.Найти(Строка.PARENT_ID) = Неопределено) Тогда
мНаУдаление.Добавить(Строка);
Продолжить;
КонецЕсли;
РасшифроватьКарту(Строка.CODEKEY);
Строка.Сотрудник = ПолучитьСотрудникаПоТабелю(Строка.TABID);
КОНЕЦЦИКЛА; // ДЛЯ КАЖДОГО Строка ИЗ ТЗ
// Удаляю ненужный мусор
Для Каждого Строка Из мНаУдаление Цикл
ТЗ.Удалить(Строка);
КонецЦикла; // Для Каждого Строка Из мНаУдаление
// Установить русские названия колонок
РусифицироватьКолонкиТаблицы(ТЗ);
Возврат ТЗ;
КонецФункции // ПолучитьСотрудников()
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Получить посещаемость
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Получить посещаемость сотрудников/сотрудника за выбранный период
//
// Функция возвращает структуру состоящую из:
// ТЗ - Тип: ТаблицаЗначений.
// ТЗ с данными полученными из запроса к базе Сигурд.
// Массив - Тип: Массив.
// Массив содержащий данные в иерархическом виде.
// * Массив с структурой сотрудников
// (Сотрудник, Имя, Карточка, Описание, Статус, Табель, Посещаемость)
// * Посещаемость - массив со структурой посещаемости по рабочим дням
// (ВремяВхода, ВремяВыхода, ЧасовНаРаботе, Примечание, Ошибка)
// ТабДок - Тип: ТабличныйДокумент
// Содержит
//
// Параметры:
// ДатаНачала - [необязательный](дата)
// параметром передается дата начала отбора,
// если опустить параметр -
// начало предыдущего месяца.
// Эта дата всегда начало дня!
// ДатаОкончания - [необязательный](дата)
// параметром передается дата начала отбора,
// если опустить параметр -
// конец предыдущего месяца.
// Эта дата всегда конец дня!
// мДверей - [необязательный](массив строк)
// массив содержащий полные названия входных дверей.
// По умолчанию регистрируются все двери
// Сотрудник - [необязательный](строка)
// имя сотрудника по которому получить данные.
// По умолчанию пустая строка - по всем сотрудникам
// Отладка - [необязательный](булево)
// если передать Истина, то в результирующей структуре
// вернет в том числе и ТабличныйДокумент с
// временем проведенным на работе и отмеченными ошибочными расчетами.
// По умолчанию - Ложь.
Функция ПолучитьПосещаемость( Знач ДатаНачала = Неопределено,
Знач ДатаОкончания = Неопределено,
Знач мДверей = Неопределено,
Знач Сотрудник = "",
Знач Отладка = Ложь) Экспорт
Если Не ПроверитьПодключение() Тогда
Возврат Неопределено;
КонецЕсли;
// Обрабатываю переданные параметры
Если ДатаНачала = Неопределено Тогда
ДатаНачала = НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
КонецЕсли;
Если ДатаОкончания = Неопределено Тогда
ДатаОкончания = КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
КонецЕсли;
// Беру заданый период + 1 день к ожидаемому, тк люди могли работать в ночь
// и желательно захватить статистику по полному рабочему дню накануне.
Период = СтрШаблон("AND L.logtime BETWEEN '%1-%2-%3 00:00:00' AND DATE_ADD('%4-%5-%6 23:59:59', INTERVAL 1 DAY)",
Формат(Год(ДатаНачала), "ЧГ=0"),
Месяц(ДатаНачала),
День(ДатаНачала),
Формат(Год(ДатаОкончания), "ЧГ=0"),
Месяц(ДатаОкончания),
День(ДатаОкончания));
Если мДверей <> Неопределено и мДверей.Количество() Тогда
Двери = "AND D.Name in (";
Для Каждого Дверь Из мДверей Цикл
Двери = СтрШаблон("%1'%2', ", Двери, Дверь);
КонецЦикла;
Двери = Лев(Двери, СтрДлина(Двери)-2) + ")";
Иначе
Двери = "";
КонецЕсли;
Если Сотрудник <> "" Тогда
Сотрудник = "AND P.Name LIKE '%"+Сотрудник+"%'";
КонецЕсли;
ТекстЗапроса = "
|# ##### ##### ##### ##### #####
|# ЗАПРОС ПРОХОДОВ
|# ##### ##### ##### ##### #####
|SELECT
| L.id AS EventID, # Код события
| L.logtime AS EventTime, # Время события
| L.devhint AS DoorID, # Код двери
| D.Name AS DoorName, # Имя двери
| IF(ord(substr(L.logdata, 5, 1)) = 1,
| 'Выход',
| 'Вход') AS Dir, # Направление прохода
| HEX(substr(L.logdata, 11, 8)) AS EventCodeKey,# Проход по карточке
| P.ID AS EmployeeID, # Код работника
| P.NAME AS Name, # Имя
| P.DESCRIPTION AS Description, # Описание
| P.POS AS Pos, # Должность / Модель
| P.TABID AS TabID, # Табельный номер
| IF(P.STATUS=1,
| 'Работает',
| 'Удален') AS Status, # Работает / Удаления
| HEX(P.CODEKEY) AS Codekey # Код карты в HEX
|FROM
| `tc-db-main`.devices AS D
| LEFT JOIN `tc-db-log`.logs AS L
| LEFT JOIN `tc-db-main`.personal AS P
| ON (L.EMPHINT = P.ID)
| ON D.ID = L.devhint
|WHERE
| substr(L.logdata,1,2) = 0xFE06
| "+Период+"
| "+Двери+"
| "+Сотрудник+"
|ORDER BY
| EmployeeID ASC
|LIMIT "+Limit+"
|";
Recordset.Open(ТекстЗапроса, Connection, 1);
ТЗ = НаборЗаписейВТаблицу();
// Расшифровываю поле с карточкой
Для Каждого Строка Из ТЗ Цикл
РасшифроватьКарту(Строка.CODEKEY);
РасшифроватьКарту(Строка.EventCodeKey);
КонецЦикла;
// Установить русские названия колонок
РусифицироватьКолонкиТаблицы(ТЗ);
Запрос = Новый Запрос("
|ВЫБРАТЬ * ПОМЕСТИТЬ ВТ ИЗ &ТЗ КАК ТЗ;
|ВЫБРАТЬ Имя,Карточка,Описание,Статус,Табель, // Работник
|ВремяСобытия, НаправлениеПрохода, ИмяДвери, КарточкаСобытия // Проходы
|ИЗ ВТ КАК ВТ УПОРЯДОЧИТЬ ПО ВремяСобытия Возр ИТОГИ ПО КодРаботника");
Запрос.УстановитьПараметр("ТЗ", ТЗ);
вРаботник = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
МассивРаботников = Новый Массив;
Посещаемость = Новый Массив;
ПОКА вРаботник.Следующий() ЦИКЛ
Работник = Новый Структура("Сотрудник,Имя,Карточка,Описание,Статус,Табель,Посещаемость");
вДанные = вРаботник.Выбрать();
вДанные.Следующий();
ЗаполнитьЗначенияСвойств(Работник, вДанные);
Работник.Сотрудник = ПолучитьСотрудникаПоТабелю(Работник.Табель);
Посещаемость = РассчитатьПосещаемость(вДанные, ДатаНачала, ДатаОкончания);
Работник.Вставить("Посещаемость", Посещаемость);
МассивРаботников.Добавить(Работник);
КОНЕЦЦИКЛА; // ПОКА вРаботник.Следующий()
// Формирую отчет
ТабДок = СформироватьТабДокПосещаемости(МассивРаботников, ДатаНачала, ДатаОкончания);
Возврат Новый Структура("ТабДок,ТЗ,Массив", ТабДок, ТЗ, МассивРаботников);
КонецФункции // ПолучитьПосещаемость()
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
#КонецОбласти
ЕСЛИ У ВАС ВОЗНИКЛИ ВОПРОСЫ, С УДОВОЛЬСТВИЕМ ОТВЕЧУ В КОММЕНТАРИЯХ ИЛИ ЛС
Related Posts
- Получение логина и пароля техподдержки 1С из базы
- Класс для вывода отчета в Excel
- Счет-фактура для УПП
- Библиотека классов для создания внешней компоненты 1С на C#
- Акт об оказании услуг (со скидками) — внешняя печатная форма для Управление торговлей 11.1.10.86
- Прайс-лист с артикулом в отдельной колонке
Обращаю внимание, что публикация упорно съедает знаки «<>» — в техпотдержку написал, надеюсь исправят.
(1)Исправили, оперативненько :3
Вот пример для расшировки карт в запросе для W26:
Показать
(3) А вот на примере карточки ‘076,07591’ как «запихнуть» обратно:
Может в будующем сделаю статью по загрузке данных в СКУД.
Но вообще добавление через MySQL запрос в целом выглядит следующим образом:
Показать
.
Добрый день, подскажите удалось ли реализовать выгрузку фото в Сигур?
(5)
Привет.
Фотки в сигуре не вели.
И Я на том месте уже не работаю.
Так что вряд ли смогу подсказать)
Но это 100% реально сделать.
(5)
Выгрузку фото сделать несложно. Кроме вставки в таблицу PERSONAL надо еще добавлять строку в таблицу PHOTO, колонки:
ID — ID объекта. =PERSONAL.ID.
PREVIEW_RASTER — Уменьшенная копия фотографии в формате JPEG в цветовом пространстве RGB *1.
HIRES_RASTER — Полноразмерная фотография в формате JPEG в цветовом пространстве RGB *1.
TS — «Версия фотографии». Целое число, которое меняется тогда и только тогда, когда меняется сама фотография (поля _RASTER). Может быть, например, хешем от изображения или временем его создания. Используется в работе кеша фотографии на стороне клиентских мест, а также кеша биометрических дескрипторов, которые строятся системой автоматически для добавляемых или изменяемых фотографий.
*1 Уменьшенная копия фотографии используется в интерфейсе системы там, где область ее отображения минимальна. Рекомендуется в качестве уменьшенной копии записывать версию фотографии, не превышающую размера 256×256 пикселей, в качестве полноразмерной — не превышающую размера 1920×1080 пикселей.
Допускается записывать в качестве уменьшенной копии тоже самое, что и в качестве полноразмерной, в т.ч. изображение достаточно большого размера.
Просто достать все карты за период в формате 000,0000. время входа, выхода. справочник персонал не ведется.
Знаем только номер карты. пример 000,12345.
Хотим получить данные по этой карте.
например запрос
select id,logtime,devhint,logdata,ord(substr(logdata,5,2)) as dir from logs where substr(logdata,1,2)=0xFE07
известен только номер xxx,12345
(8)
Это вопрос?)
(9)да
if(substr(HEX(logdata), 1, 2) = 18,
CONCAT(
RIGHT(CONCAT(‘000’, CONV(substr(HEX(logdata), 3, 6), 16, 10) DIV 65536),3),
‘,’,
RIGHT(CONCAT(‘00000’, CONV(substr(HEX(logdata), 3, 6), 16, 10) % 65536), 5)),
NULL)
а что данное условие делает? substr(HEX(logdata), 1, 2) = 18
(11)
разобрался.
Может помнишь как достать из 0xFE0700010103000000001800F20C00000000FFFF код карты 000,61664
(12)
Насколько помню, проверяет является ли карта в формате Wiegand-26, в противном случае возвращает null, но это было давно и не правда.
Вот как расшифровать в mysql запросе:
Показать
Смысл тут — взять кусочек HEX, превратить его в число. Поделить на 65536 и записать в формате 000
Затем взять еще кусочек HEX, снова в число, получить остаток от деления на 65536 и записать в формате 00000
Затем объединить это дело в 000,00000
Вот так функцией 1с:
Показать
Нет функций
СтрШаблон()
СтрРазделить()
(14) У вас очень старая платформа?
СтрШаблон — подставляет параметры в строку. Аналог в других языках — format
СтрРазделить — разбивает строку в массив подстрок по заданому разделителю. Аналог в других языках — split
(15) 1С:Предприятие 8.3 (8.3.9.2170)
(16)http://v8.1c.ru/o7/201408str/index.htm
Значит режим совместимости стоит)
Понял режим совместимости Версия 8.2.13
Показать
(19) Ну да, можете поискать эти функции в общем модуле бсп по работе со строками.
Но с 8.3.6 это включено в платформу.
СтрШаблон заменил на СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку()
СтрРазделить это СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок()
(0) Подскажите как называется имя базы по умолчанию? Представители установили, а имя базы для подключения не знают, доступа у меня к серверам нет.
Сервер = есть
Порт = есть
Имя Базы = НЕТ
Пользователь = есть
Пароль = есть
(23)
`tc-db-main` — справочники
`tc-db-log` — события
Здравствуйте. Подскажите, пожалуйста, где хранятся номера пропусков, если пропуск не один? В таблице personal хранится только одна запись по сотруднику. Соответственно, одна запись CODEKEY и одно значений пропуска. В самом приложении СИГУР вводим по сотруднику несколько пропусков. Как найти номер второго пропуска?
(25) Привет, честно говоря, не помню и сугура под рукой нет уже давно.
Но точно получал и выводил несколько пропусков по сотруднику.
Возможно в списке сотрудников по одному человеку прям несколько записей.
(26)Запросом по сотруднику только одну строку получаем. И ID сотрудника — это ключевое поле по таблице.
(27) Не помню, честно)
Все оказалось очень просто: первый пропуск хранится в таблице Personal. Все последующие номера пропусков находятся в таблице personal_key.
«ЛюбаяДес » что за функция?
(30) Перевод в десятичную систему счисления из шестнадцатиричной.
А можете помочь с преобразованием номера карты em-marine вида «0008599310» в код Wiegand «000003066E1D»?=) буду крайне признателен, самому знаний не хватает и где взять найти не могу)
(32) Неа, не знаю я как формируется emmarine.
По поводу виганда — просил у саппорта СКУДа скинуть мне данные.
Они скинули экселевский файл с формулой.
(32)
1) переводите 0008599310 в двоичную форму, получается:
100000110011011100001110
2) дополняете слева нулями до 24 бит:
100000110011011100001110 (в данном случае их и так было 24)
3) разбиваете по-середине на две части по 12 бит:
100000110011 011100001110
4) считаете кол-во единиц в левой и правых частях:
100000110011 => N1=5
011100001110 => N2=6
5) C1 = N1%2, т.е. остаток от деления N1 на 2.
C1 = 1
6) C2 = (N2+1)%2, т.е. остаток от деления (N2+1) на 2.
C2 = 1
7) добававляете C1 слева двоичного представления, C2 — справа:
1 100000110011 011100001110 1
8) воспринимаете результат как 26-и битное целое, переводите его в hex:
3066E1D
9) дополняете слева нулями до 12 знаков:
000003066E1D
Очевидно же все.
(34) разобрался уже, спасибо. кому нибудь точно пригодится, в инете в большинстве ресурсов как то коряво написано или не полностью
Возможно ли с помощью данной обработки выгружать данные в табель, если да то подскажите пожалуйста как? как её применить в управляемых формах? Спасибо.
(36) Это скорее полуфабрикат для разработчиков.
Сигурда под рукой уже с год нету.
Вообще это реализуемо естественно.
(38)
Судя по всему вы не объявили переменные в модуле объекта:
Огромное спасибо. Теперь намного лучше, но появились ещё 2 ошибки помогите пожалуйста разобраться и с ними
инициализации модуля: Обработка.Сигур.Форма.Форма.Форма
по причине:
{Обработка.Сигур.Форма.Форма.Форма(5,12)}: Неопознанный оператор
Connection <<?>>- COM Объект ADODB.Connection
{Обработка.Сигур.Форма.Форма.Форма(51,1)}: Определения процедур и функций должны размещаться перед операторами тела модуля
<<?>>Функция Конструктор( Знач Драйвер,
(40)
1) наверное забыли установить драйвер для работы с MySQL
2) не там переменные объявили.
Они должны объявлятся в самом начале модуля объекта.
Вот не задача, драйвер установлен и переменные указаны правильно, да вот всё равно ошибки не прекращаются
{Обработка.Сигур.МодульОбъекта(2,12)}: Неопознанный оператор
Connection <<?>>- COM Объект ADODB.Connection (Проверка: Сервер)
{Обработка.Сигур.МодульОбъекта(48,1)}: Определения процедур и функций должны размещаться перед операторами тела модуля
<<?>>Функция Конструктор( Знач Драйвер = «SQL Server», (Проверка: Сервер)
(42)
Либо переменные объявили не там где надо, либо точку с запятой установили после «КонецПроцедуры»
Спасибо конечно за подсказки, но увы не чего не получается с этими ошибками, быстрее всего нужно смотреть саму обработку для полного анализа
Добрый день! Подскажите пожалуйста как выполнить загрузку из mysql с определенного id при попытке запроса WHERE ID > ‘2570’ 1с всё равно обходит все записи. Спасибо.
(45) Поставьте себе какойнить удобный запросник или phpmyadmin или datagrip. Там и эксперементируйте.
Эксперементировал там отрабатывает правильно в 1с нет
Добрый день!
Добрый день!
Настраиваю новую базу данных сигура.
помню что для работы с персоналом нужна таблица personal в tc-db-main
Но не могу подключиться к базе
логин root
а пароль какой? Пустой, sphinx и т.п. не подходят….
(49) Позвони в саппорт, они вежливо и сразу отвечали на все вопросы.
Также на оффсайте есть ман.
Я уже два года не занимаюсь сфинксом-сигуром, ничего не помню)