Пример реализации обмена с оборудованием через winsocket на управляемых формах по протоколу TCP

Публикация № 574235

Разработка - Практика программирования

Объединяя опыт коллег с данного ресурса, хочу поделиться своим решением с подключением контроллера контроля доступа к 1С УНФ. Здесь описан метод без использования ActiveX, который не работает на УФ.

Задача была по поводу наладки обмена информацией между 1С УНФ и контроллера управления доступа клиентов. Имеется описание протокола для связи с контроллером по TCP. Контроллер может работать в режиме сервера, прослушивая определенный порт принимая с него команды и отправляя обратно ответы. Решил использовать WinSocket, благо информации много.

Вот неплохая публикация, где рассматриваются режимы клиента и сервера с использованием ActiveX://infostart.ru/public/119982/

Одна беда - УФ. ActiveX  - не поддерживается.

Итак приступим.

Прикручиваем к УФ
ActiveX не прижился на УФ. Метод с офисом, который рассматривался здесь - сложноват, поэтому подключаем Winsocket как COMобъект.

Как же его хранить? Будем хранить его в параметрах сеанса. Оттуда он доступен и клиенту и серверу. 

Процедура ПриОткрытииНаСервере()
    Контроллер = Новый COMОбъект("mswinsock.winsock"); 
    ПараметрыКонтроллера = Новый Структура("Адрес, Порт");
    ПараметрыКонтроллера.Адрес = "xxx.xxx.xxx.xxx";
    ПараметрыКонтроллера.Порт = "pppp";
    
    СтруктОбъекта = Новый Структура("Контроллер",Контроллер);
    ПараметрыСеанса.Z5=ПоместитьВоВременноеХранилище(СтруктОбъекта,Новый УникальныйИдентификатор());
    ИнициализироватьПодключение(ПараметрыКонтроллера);
КонецПроцедуры

Заметим, что COMобъект мы спрятали в структуру. Как уже обсуждалось на Инфостарте, COMобъекты не поддерживают сериализацию. А если "спрятать" его в структуру, ошибок не будет:

 СтруктОбъекта = Новый Структура("Контроллер",Контроллер);
    ПараметрыСеанса.Z5=ПоместитьВоВременноеХранилище(СтруктОбъекта,Новый УникальныйИдентификатор());

Рассмотрим подключение. Отдельное спасибо Андрею, автору публикации: //infostart.ru/public/119982/ и участникам обсуждения за знакомство с winsocket.

&НаСервере
Процедура ИнициализироватьПодключение(ПараметрыПодключения)    
    ws = ПолучитьИзВременногоХранилища(ПараметрыСеанса.Z5).Контроллер;
    Если ws.State <> 7 тогда
         Если ws.State <> 0 Тогда
            ws.Close();
        КонецЕсли;
        
        ws.RemoteHost = СокрЛП(ПараметрыПодключения.Адрес);
        ws.RemotePort = СокрЛП(ПараметрыПодключения.Порт);
        ws.Connect();
    Иначе
        ws.Close();
        
        ws.RemoteHost = СокрЛП(ПараметрыПодключения.Адрес);
        //        ws.RemoteHostIP = СокрЛП(ПараметрыПодключения.Адрес);
        ws.RemotePort = СокрЛП(ПараметрыПодключения.Порт);
        
        ws.Connect();
    КонецЕсли;
    Объект.Статус = ws.state; //Сохраняем статус чтобы отображать его на форме
    
КонецПроцедуры

Все, подключились. При открытии формы нашей обработки мы хотим получить некоторые данные с контроллера.

Работа с контроллером будет происходить асинхронно. Отправляем запрос, затем ждем ответ. Дождавшись обрабатываем его и отправляем новый запрос и т.д.

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

&НаКлиенте
Процедура ПриОткрытии(Отказ) 

//Мы будем использовать сканер и считыватель
	ИспользоватьПодключаемоеОборудование=Истина;
	// ПодключаемоеОборудование
	МенеджерОборудованияКлиентПереопределяемый.НачатьПодключениеОборудованиеПриОткрытииФормы(ЭтаФорма, "СканерШтрихкода,СчитывательМагнитныхКарт");
	// Конец ПодключаемоеОборудование
//--------------------------------------------
	ПриОткрытииНаСервере();
	
	//Заблокируем форму от изменений
	УправлениеДоступностью(Ложь);
	
	//Пошлем первую команду на получение списка контроллеров
	ПодключитьОбработчикОжидания("ПолучитьСтатус",10);
	Объект.ТипКоманды = "20";
	Объект.Команда = "ПолучитьАдресКонтроллера";
	Объект.ТекстСообщения = "00 08 08 01 00 00 00 00";
	ПодключитьОбработчикОжидания("ВыполнитьКоманду",1);
	
	//Подключим периодический опрос контроллеров
	Объект.НомерВыполняемойКомандыОпроса = 1;
	ПодключитьОбработчикОжидания("ПериодическийОпрос",1);   //здесь могут крутиться несколько команд, которые получают события и отправляют изменения
	
КонецПроцедуры

Сама процедура отправки команды, которая в нашем случае вызывается многократно 1 раз в секунду, на случай, если контроллер чем-то занят.

&НаКлиенте
Процедура ВыполнитьКоманду()
    
    ПолучитьСтатус();
    Элементы.Статус.Заголовок = Объект.Статус;
    Если Объект.Статус = 0 Тогда   //Не подключено 
        ПриОткрытииНаСервере();
        Возврат;
    ИначеЕсли Объект.Статус = 6 Тогда // еще идет подключение
        Возврат;
    КонецЕсли;
    УправлениеДоступностью(Ложь); //ничего нельзя делать на форме
    Результат = ОтправитьДанные();   // Ниже функция отправки
    Элементы.Статус.Заголовок = Объект.Статус;
    Если Результат Тогда
        Объект.Лог = Формат(ТекущаяДата(),"ДЛФ=DT") + ": " + Объект.Команда +" --> " + Символы.ПС + Объект.Лог;
        Объект.Лог = Объект.ТекстСообщения + Символы.ПС + Объект.Лог;
        ОтключитьОбработчикОжидания("ВыполнитьКоманду"); //Команда выполнилась, отключаем этот обработчик
        ПодключитьОбработчикОжидания("ПолучитьОтвет",1); //Подключаем ожидание ответа Многократно    
    Иначе
        Если Объект.Статус = 9 Тогда //ошибка, не расшифровать нафиг
            ПриОткрытииНаСервере(); //реконнект (кстати не помогает. Только отключение кабеля)
        КонецЕсли;
    КонецЕсли;       
    
КонецПроцедуры

Функцию ОтправитьДанные() мы рассмотрим ниже, а пока из кода видно, что после отправки команды на контроллер мы подключаем второй обработчик ожидания на получение ответа контроллера. ActiveX winsocket, который мы в силу обстоятельств не можем использовать, имеет очень важное событие WinSocketDataArrival, которое возникает при получении данных. Нам придется обходиться без него. Мы просто 1 раз в секунду будем читать возможно полученные ответы.

&НаКлиенте
Процедура ПолучитьОтвет()
    Элементы.Статус.Заголовок = Объект.Статус;
    Результат = ПолучитьОтветНаСервере(); //ф-я ниже    
    Элементы.Статус.Заголовок = Объект.Статус;
    Если Результат Тогда
        ОтключитьОбработчикОжидания("ПолучитьОтвет"); //ответ получен, отключаем обработчик
        Объект.Лог = Формат(ТекущаяДата(),"ДЛФ=DT") + ": " +Объект.Команда +" <-- " + Символы.ПС + Объект.Лог;
        Объект.Лог = Объект.ОтветКонтроллера + Символы.ПС + Объект.Лог;
        ВыполнитьОбработкуОтвета(); // Здесь много условий которые получают название команды и соответственно ее обрабатывают
    Иначе
        ПриОткрытииНаСервере();  //реконнект (не знаю, зачем я его делаю))))
    КонецЕсли;       
    
КонецПроцедуры

Собственно функция отправки:

&НаСервере
Функция ОтправитьДанные()
    Результат = Ложь;
    Контроллер = ПолучитьИзВременногоХранилища(ПараметрыСеанса.Z5).Контроллер; //получили winsocket из параметров сеанса
    buff = ПреобразоватьДляОтправки(Объект.ТекстСообщения);  // преобразование в массив HEX требуется для моего контроллера
    buff[0] = "&H" + Объект.ТипКоманды;
    ВОтправку = "";
    Для н = 0 По buff.Количество()-1 Цикл
        ВОтправку =ВОтправку + buff[н] + " ";    
    КонецЦикла;

    Объект.Статус = Контроллер.State;
    
    Если Контроллер.State = 7 тогда //Подключились удачно, отправляем данные
        Попытка
            Для н = 0 По buff.Количество()-1 Цикл
                Контроллер.SendData(Chr(buff[н])); // отправляю посимвольно из буфера  Chr(Код) - функция с VBScript которая преобразует из HEX в символ.
            КонецЦикла;
            Результат = Истина;
        Исключение
        КонецПопытки;
      КонецЕсли;    
    Возврат Результат;    
КонецФункции

..и функции получения ответа, которые вызываются ежесекундным обработчиком получения ответов контроллера:

&НаСервере
Функция ПолучитьОтветНаСервере()
	Результат = "";
	Попытка
		Результат = ПолучитьДанныеСКонтроллера();
		Объект.ОтветКонтроллера = Результат;
		Возврат Истина;
	Исключение
		Возврат ложь;
	КонецПопытки;
КонецФункции

&НаСервере
Функция ПолучитьДанныеСКонтроллера()
	Контроллер = ПолучитьИзВременногоХранилища(ПараметрыСеанса.Z5).Контроллер;
	Ответ = "";
	Пока Истина Цикл
		Результат = "";
		Контроллер.GetData(Результат);
		Если НЕ Результат = "" Тогда
			Ответ = Ответ + Результат;
		Иначе
			//Преобразовать
			БуферПриема = СтрокуВМассивы(Ответ);
			Масс = БуферПриема[0];
			м4 = Неопределено;
			Результат = Преобразовать5_4(Масс,М4);
			Расшифровано = "";
			Для н = 0 По м4.Количество()-1 Цикл
				Расшифровано = Расшифровано + М4[н] + " ";
			КонецЦикла;
			Объект.ОтветКонтроллера = Расшифровано;
			Прервать;
		КонецЕсли;
	КонецЦикла;	
	Возврат Объект.ОтветКонтроллера;
КонецФункции


Так, что мы уже видим, что чтобы отправить команду на контроллер мы должны выполнить следующий код:

Объект.ТипКоманды = "20";
    Объект.Команда = "ПолучитьАдресКонтроллера";
    Объект.ТекстСообщения = "00 08 08 01 00 00 00 00";
    ПодключитьОбработчикОжидания("ВыполнитьКоманду",1);

Дальше все выполнит пара обработчиков ожидания "ВыполнитьКоманду" и "ПолучитьОтвет".

По окончании выполнения команды и получения ответа контроллера будет вызвана процедура ВыполнитьОбработкуОтвета(), которая выполнит требуемые действия с полученным ответом. Не секрет, что некоторые команды зависят от предыдущих. Например, в моем случае для получения всех карт зашитых в контроллер требуется выполнить следующие действия:

1. Запросить адрес последней карты. Выяснить сколько байт занимают все карты, разбить на блоки по 64 байта (1 условный блок хранения в контроллере)

2. Запросить 1 блок

3. Получить ответ - обработать

4. Запросить 2 блок - обработать

........

n. Запросить неполный последний блок

n+1. Обработать.

В этом случае в процедуре ВыполнитьОбработкуОтвета() мы зацикливаем выполнение команд, прямо в этой процедуре запуская на выполнение новую команду.

Функция обработки полученных ответов:

&НаКлиенте
Процедура ВыполнитьОбработкуОтвета()
//    БуферПриема = СтрокуВМассивы(Объект.ОтветКонтроллера);
    Если Объект.Команда = "ПолучитьАдресКонтроллера" Тогда
        М4 = ОтветВМассив();
        ФлагПриема = Истина;
        //Расшифруем полученные данные
        i = 8;
        Пока i < 20 Цикл
            текАдр = АдресКонтроллера(М4[i], i - 8);
            Если ТекАдр.Количество()>0 Тогда
                Для Каждого Эл Из ТекАдр Цикл
                    Объект.СписокКонтроллеров.Добавить(Эл.Значение);
                КонецЦикла;
            КонецЕсли;
            i = i + 1;
        КонецЦикла;
        Объект.Команда = "";
    ИначеЕсли Объект.Команда = "СписокКарт" Тогда
..........................................
    КонецЕсли;
    УправлениеДоступностью(Истина);    
КонецПроцедуры

Почему все так сложно? Дело в том, что SendData() отправляет только когда прекращается активность. Объясню.

Контроллер.sendData("что-то-там");
текВремя  = ТекущаяДата();
Пока Истина Цикл
            Если ТекущаяДата() > текВремя + 10;//Цикл задержки 10 секунд Тогда
                 Прервать;
            КонецЕсли;
КонецЦикла;
Получаем = Контроллер.GetData();

Не работает. Отправка произойдет по окончании выполнения всего кода текущей процедуры, которую мы вызвали, предположим, нажатием на кнопку. Можете проверить.

Итак в заключении.

Предложенный вариант не претендует на оригинальность, но зато работает. Медленно, но работает.

Надеюсь, что мой опыт кому-нибудь пригодится.

Однако, есть мнение. Кому не жалко немного времени, создать ВК с методами:
1. Подключить(Адрес,Порт) Возвращает Истина, Ложь
2. ОтправитьСтроку(Строка) Возвращает Истина Ложь
3. ПрочитатьОтвет() Возвращает ответы, накопленные в буфере Возможен вариант, В какой-либо переменной появляется ответ, который на стороне 1С можно прочитать и/или удалить, если прочитали
4. Отключить 

Там строк 50 текста будет, которые повысят стабильность, избавят от асинхронности в 1С, которая требует обработчиков, которые работают 1 раз в секунду и замедляют общение с устройствами.

Понимаю, что можно было организовать иначе, но основное требование - минимум изменений. Добавлена в конфигурацию только: переменная Z5 в параметры сеансов.

Если есть что сказать, присоединяйтесь к общению. Я мог что-то упустить. 1С на месте не стоит.

Видео с примером работы с контроллером из 1С.

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. asved.ru 35 11.01.17 10:24 Сейчас в теме
Засунуть COMОбъект в параметры сеанса временное хранилище, да еще по произвольному адресу - это, конечно, сильный ход. И неожиданный.

Вы его еще на клиента передать попробуйте. Или в базу записать.
3. asdfgcom 330 11.01.17 15:22 Сейчас в теме
(1) этот метод как раз рассматривался на инфостарте. Очень выручил. Глобально не получается держать COMобъект, т.к. после выполнения на сервере и повторном входе переменная переинициализируется. В реквизитах объекта держать нельзя. Они доступны клиенту, а COMобъекты не сереализуются. Как тогда? Остается хранилище. Как передать несереализуемый объект? Прячем его в, например, структуру...

(2) попробую.

Только что перепроверил, почему не работал "ДобавитьОбработчик". Заставил работать по событиям.
Где-то накосячил с передачей между клиентом и сервером, что вызывало appCrash 1с.exe
На самом деле все будет гораздо проще.

ДобавитьОбработчик ws.Connect, Connect; 
ДобавитьОбработчик ws.ConnectionRequest, ConnectionRequest; 
ДобавитьОбработчик ws.DataArrival, DataArrival;
ДобавитьОбработчик ws.Error, WinSocketError;

И все взлетело. Избавился от ежесекундных обработчиков.
Статью перепишу на днях.
4. asved.ru 35 11.01.17 17:23 Сейчас в теме
(3) Как вы думаете, что из себя представляет COMОбъект, и что помещается во временное хранилище?
И что Вы достанете из хранилища в следующем вызове, когда следующий вызов будет исполняться на другом сервере кластера, или после перезапуска процесса? Или после разрыва сетевого соединения?

jONES1979; +1 Ответить
5. asdfgcom 330 11.01.17 21:13 Сейчас в теме
(4) Надеюсь, я Вас правильно понял.
В Параметрах сеанса мы держим только строку с адресом временного хранилища в котором лежит наш COMобъект. Методика, описана на волшебном форуме (не уверен, что можно явно ссылаться на сторонние форумы, поэтому поиск) "Хранение COM Объектов на Сервере ТонкогоКлиента Как сохранить COM-объект на Сервере между СервернымиВызовами. Автор статьи: H A D G E H O G s"
На счет другого сервера кластера - не знаю... Но и не надо, надеюсь. Ведь COMобъект в хранилище, адрес и уникальный идентификатор у нас имеется. Всегда поднимем объект.
После разрыва сетевого соединения получим ошибку, переподключимся и сунем обратно адрес на хранилище.
7. asved.ru 35 12.01.17 14:58 Сейчас в теме
(5)
Всегда поднимем объект.


Поднимите объект через 21 минуту неактивности.

Это работает исключительно потому, что сериализация и собственно запись во временное хранилище производится отложенно. Т.е. несериализуемая ссылка на COM-объект находится в кэше рабочего процесса. Как только сервер попытается ее сериализовать - тут-то она и уничтожается.

Другой сервер кластера или клиент при попытке получения значения инициирует его физическую сериализациию, т.к. обращается к сервису сеансовых данных. Т.е. обращение к объекту с другого сервера кластера уничтожит его и на первом сервере.
9. asdfgcom 330 12.01.17 17:57 Сейчас в теме
(7)(8) Приветствую, Антон!
Да, все верно. Однако в моем случае не критично.
Winsocket используется только для связи с оборудованием. Во время обращения к нему соединение не потеряется. Факт. Если COMОбъект теряется из временного хранилища (при простое), то ошибка соединения - переподключение с переинициализацией COMобъекта. Я этого даже не замечал. Для интереса, поставлю точку в отладчике в процедуре переподключения, убедиться, что соединение теряется. Переинициализацию сделал как раз из-за предупреждения в вышепредложенной статье автора H A D G E H O G s:
"ComОбъект теряется на 20 -ой минуте его "неиспользования". Так сделали 1С. Столько живет объект во временном хранилище, если у него нет идентификатора - формы владельца. Лечение просто - раз в 500 секунд - считывать COMОбъект из Временного хранилища".
13. asdfgcom 330 12.01.17 19:39 Сейчас в теме
(1) Антон, прошу прощения за невнимательность.
Вы имели в виду мою неточность в описании, точнее некорректное построение фразы:

"Заметим, что COMобъект мы спрятали в структуру... А если "спрятать" его в структуру, ошибок не будет"

Точнее было бы сказать. ...а если спрятать его в структуру, разместить во временное хранилище, тогда ссылку на временное хранилище мы можем передать в переменную, хранимую в параметрах сеанса для того, чтобы использовать ее и на клиенте, и в серверных вызовах без переинициализации самого объекта.. И т.д. (получилось много букв. Я бы читать не стал с этого места дальше.))))
2. mdl@andi72.ru 11.01.17 10:37 Сейчас в теме
ActiveX в УФ поддерживается, не официально. Делал через реализацию интерфейсов для ie:

GetInterfaceSafetyOptions, SetInterfaceSafetyOptions

ну естественно под win
6. Darklight 27 12.01.17 14:33 Сейчас в теме
Большое списбо за статью, познавательно!
Сам храню COM-объекты через модули повторного использования - тоже ретушируются (без упаковки в структуру; как возвращаемые значения), но есть свои неудобства такого подхода.
Но технология COM - это уже прошлый век.
Что же делать под Linux?
10. asdfgcom 330 12.01.17 18:04 Сейчас в теме
(6) Как говорится, спасибо за спасибо.
Что Вы подразумевали под: "Что же делать под Linux?"
COMобъекты может и устарели, но с ними легко быстро не зная ничего кроме 1С и протокола или описания методов начать работать над задачей.
К данной работе я подходил около месяца. Пытался сначала "врапить" по технологии NET, однако знаний не хватало и времени. По протоколу через winsocket надоумил сам производитель оборудования. Уже через неделю описал все команды, через 3 недели готовый прототип обмена. Сейчас "пилю" интерфейс, засовываю в расширение (для этого и понадобились параметры сеанса). К сожалению придется добавлять регистр сведений, синхронизировать его с данными из контроллера.
11. Darklight 27 12.01.17 18:16 Сейчас в теме
(10)Как работать сокeтами под Linux
12. asdfgcom 330 12.01.17 18:30 Сейчас в теме
(11) 1С у заказчика под Windows. Однако, в свете последних событий и импортозамещения, придется скоро осваивать не только сокеты под Linux.
14. asdfgcom 330 28.01.17 12:23 Сейчас в теме
В данный момент отказались от использования WinSocket и работой с контроллером непосредственно из 1С. 1С работает с контроллером очень медленно. На "слабых" машинах приходится полностью отключать автоматический опрос, т.к. обработчики событий начинают подавать команды не по очереди, а одновременно из-за медленной обработки событий и задач. Создавать кэш команд не хочется, решили всю низкую часть перенести на java.
Однако, для простых запросов вышеописанный способ общения может пригодиться.
15. vdenu 01.03.17 17:21 Сейчас в теме
Спасибо за статью, но вероятно я невнимательно её изучил и так и не понял два вопроса:
1. Каким же образом COM-объект созданный на сервере и затем помещённый в структуре во Временное хранилище может стать доступным на стороне клиента? ПолучитьИзВременногоХранилища() не срабатывает со стандартной ошибкой "Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа" Т.е. программа знает, что в структуре я "спрятал" com
2. Если я создаю Винсокет на стороне сервере, то как использовать ДобавитьОбработчик?
16. asdfgcom 330 01.03.17 19:01 Сейчас в теме
(15)
1. Идя не нова, "Хранение COM Объектов на Сервере ТонкогоКлиента Как сохранить COM-объект на Сервере между СервернымиВызовами. Автор статьи: H A D G E H O G s"

Контроллер = Новый COMОбъект("mswinsock.winsock");
.......

СтруктОбъекта = Новый Структура("Контроллер",Контроллер);
ПараметрыСеанса.Z5=ПоместитьВоВременноеХранилище(СтруктОбъекта,Новый УникальныйИдентификатор());

Помещаем в параметры сеанса, чтобы можно было дотянуться.
(мне нужно было, чтобы можно было использовать и на стороне конфигурации и на стороне расширения.)

2. Второй способ реализован в данный момент.

Следующим сообщением (вставка кода не работает)

17. asdfgcom 330 01.03.17 19:14 Сейчас в теме
Вынес все в клиент. Только в этом случае работают обработчики событий. Объявил переменную Контроллер. Ограничил весь функционал одной обработкой.

Прошу прощения, не работает нормально вставка кода...

&НаКлиенте
Функция ВыполнитьПодключениеККонтроллеру()
	Попытка
		Контроллер = Новый COMОбъект(Объект.AddINКомпоненты); 
		ПараметрыКонтроллера = Новый Структура("Адрес, Порт");
		ПараметрыКонтроллера.Адрес = Объект.АдресПодключения;
		ПараметрыКонтроллера.Порт = Объект.ПортПодключения;
		
		Если Контроллер.State <> 7 тогда
			
			Если Контроллер.State <> 0 Тогда
				Контроллер.Close();
			КонецЕсли;
			
			Контроллер.RemoteHost = СокрЛП(ПараметрыКонтроллера.Адрес);
			Контроллер.RemotePort = СокрЛП(ПараметрыКонтроллера.Порт);
			
			Контроллер.Connect();
		Иначе
			Контроллер.Close();
			
			Контроллер.RemoteHost = СокрЛП(ПараметрыКонтроллера.Адрес);
			//		ws.RemoteHostIP = СокрЛП(ПараметрыПодключения.Адрес);
			Контроллер.RemotePort = СокрЛП(ПараметрыКонтроллера.Порт);
			
			Контроллер.Connect();
		КонецЕсли;
		
		ДобавитьОбработчик Контроллер.Connect, Connect; 
		ДобавитьОбработчик Контроллер.ConnectionRequest, ConnectionRequest; 
		ДобавитьОбработчик Контроллер.DataArrival, DataArrival;
		ДобавитьОбработчик Контроллер.Error, WinSocketError;
		
			Возврат Истина;
	Исключение
		Возврат Ложь;	
	КонецПопытки;
КонецФункции
Показать

Платформа: 8.3.9.1850
18. vdenu 02.03.17 09:29 Сейчас в теме
(17) Да, на клиенте действительно работает, а на сервере технология не живёт и ком-объект в хранилище хранится только для сервера, никакая упаковка не позволяет его получить на клиенте из хранилища, увы. Кстати, спасибо за статью - подтолкнула к экспериментам.
19. asdfgcom 330 02.03.17 11:00 Сейчас в теме
(18) Настойчиво рекомендую почитать: "Хранение COM Объектов на Сервере ТонкогоКлиента Как сохранить COM-объект на Сервере между СервернымиВызовами. Автор статьи: H A D G E H O G s"
20. Bukaska 134 02.03.17 11:16 Сейчас в теме
(17)Да почему.. вставка кода работает. Выделили текст и нажали на значок: </> - и готово
21. asdfgcom 330 02.03.17 14:57 Сейчас в теме
(20) У меня браузер Chrome. Иногда (не всегда) после нажатия на </> не открывается форма вставки кода, а появляется то же окно редактирования сообщения, только без набранного текста. Не разобрался пока в чем дело.
22. vdenu 02.03.17 15:10 Сейчас в теме
Евгений, я недостаточно точно выразился. Вот ваша цитата: "Как же его хранить? Будем хранить его в параметрах сеанса. Оттуда он доступен и клиенту и серверу. " Хранить в структуре его (ComОбъект) можно, но доступен он всегда только для сервера и никогда для клиента. (Соответственно в случае с winsocket подобное решение лишено смысла)
23. asdfgcom 330 02.03.17 18:48 Сейчас в теме
24. Alexoidic 25.04.20 20:06 Сейчас в теме
Здравствуйте!!! Написал TcpClient на 1с, TCPServer написан на си шарпе, Отправка данных работает отлично, не могу получить ответ с сервера, не отрабатывает событие WinSocketDataArrival. Никак не могу понять почему.

#Область ComObject_WinSocket
&НаКлиенте
Процедура InitWinSocketClient()
	Порт = 8888;
	Хост="10.4.1.8"; 
	WinsocketClient = Новый COMObject("mswinsock.winsock");		
	ДобавитьОбработчик  WinsocketClient.Connect, ПриПодключенииКлиентаКCерверу; 
	ДобавитьОбработчик  WinsocketClient.SendProgress, WinSocketSendProgress;
	ДобавитьОбработчик  WinsocketClient.SendComplete, WinSocketSendComplete;
	ДобавитьОбработчик  WinsocketClient.DataArrival, WinSocketDataArrival;
	ДобавитьОбработчик  WinsocketClient.Error, WinSocketError;
	WinsocketClient.RemoteHost = Хост;
	WinsocketClient.RemotePort = Порт;
	Попытка
		WinsocketClient.Connect();
		// само подключение состоится только после выхода из текущего метода
		// после подключения выполнится ПриПодключенииКлиентаКсерверу

		Исключение
	КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура WinSocketSendProgress(bytesSent, bytesRemaining)
	Состояние("Передача списка",(bytesSent+bytesRemaining)/bytesSent*100);
КонецПроцедуры

&НаКлиенте
Процедура WinSocketSendComplete()
	
	Сообщить(Строка(ТекущаяДата()) + " | Отправка данных завершена!!! ");

КонецПроцедуры

&НаКлиенте
Процедура WinSocketError(Number, Description, Scode, Source, HelpFile,HelpContext, CancelDisplay)

    Сообщить("Ошибка передачи:"+ Description);

КонецПроцедуры

&НаКлиенте
Процедура WinSocketDataArrival(bytesTotal)

	ТкстСообщения = ""; 
			WinsocketClient.GetData(ТкстСообщения, bytesTotal);
    Сообщить(ТкстСообщения);

    	
КонецПроцедуры

&НаКлиенте
Процедура ПриПодключенииКлиентаКCерверу() Экспорт
	//КодДляПередачи=686;
//	Если ЗначениеЗаполнено(ЗаписьJSON) Тогда
		WinsocketClient.SendData(ЗаписьJSON.Закрыть());
//	КонецЕсли;
	УдалитьОбработчик WinsocketClient.Connect, ПриПодключенииКлиентаКCерверу; 
КонецПроцедуры
#КонецОбласти
Показать
Оставьте свое сообщение

См. также

Звуковое управление в 1С 8.3 Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

В данной статье описано создание библиотеки для звукового управления (выполнение команд голосом) для платформы 1С 8.3. Задача была поставлена так, чтобы модуль функционировал непосредственно на клиенте 1С, осуществляя управление формами, и взаимодействовал с интерфейсом.

16.03.2021    2802    velemir    30    

Полезные примеры СКД, ч.2

Практика программирования v8 v8::СКД Бесплатно (free)

Еще несколько примеров решения задач в СКД.

06.04.2021    3297    Neti    7    

Неочевидные нюансы записи управляемой формы

Практика программирования v8 v8::УФ Платформа 1C v8.2 1cv8.cf Бесплатно (free)

Разберем несколько нюансов записи управляемой формы.

02.04.2021    4743    SeiOkami    49    

Полезные примеры СКД, ч.1

Практика программирования v8::СКД Бесплатно (free)

Подборка видео по решению различных задач в отчетах на СКД.

30.03.2021    5189    Neti    18    

Serverless (Faas) в 1С. Создание и вызов Yandex Cloud Functions Промо

Универсальные функции Практика программирования v8 Бесплатно (free)

"Я не могу просто взять и скопировать код с гитхаба", "у нас 1С микросервисами окружена", "возможностей мало" - частые фразы 1С разработчиков. которым не хватает возможностей платформы в современном мире. Faas, конечно, история не новая, но нас сдерживало 152ФЗ и задержки по пингам. Для того, чтобы действительно использовать в 1С код, к примеру, на Python, надо было приложить усилия. Теперь всё намного проще - берём и используем.

28.12.2020    5183    comol    31    

Обзор полезных методов БСП 3.1.4

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Бесплатно (free)

Библиотека стандартных подсистем (далее - БСП) является частью любой типовой конфигурации, поэтому умение применять готовые процедуры и функции повышает качество разработки и избавляет от написания лишнего кода. К сожалению, не у всех есть время и упорство овладеть всей документацией, поэтому я собрал воедино наиболее популярный функционал.

25.03.2021    12555    rayastar    45    

Расширенный автоподбор при вводе по строке в поле ввода в управляемых формах

Практика программирования v8 v8::УФ 1cv8.cf Бесплатно (free)

Началось все с того, что штатный автоподбор при вводе по строке в поле ввода для некоторых больших справочников устраивать перестал. Вообще, для способа поиска строки "Любая часть" он работает на первый взгляд очень хорошо: работает как полнотекстовый (т.е. по нескольким словам) даже без активации полнотекстового поиска, красиво подсвечивает слова поиска в результатах. Казалось бы, все отлично. Но есть неприятное ограничение - всего лишь 10 значений в результирующем списке (у вас может быть несколько больше, так как платформа неявно добавляет результаты поиска по истории ввода). Для небольших справочников или справочников с разнородным ассортиментом все хорошо. Но не в моей ситуации. А простых путей увеличить количество выдаваемых строк на момент написания статьи мне обнаружить не удалось. Пришлось полностью переопределять автоподбор. Ниже речь пойдет именно об этом. И, к слову, в типовых конфигурациях для некоторых справочников используются похожие приемы для увеличения количества строк результата автоподбора.

21.01.2021    1788    herfis    7    

Программное копирование узла/строки дерева значений на управляемой форме (УФ, ДанныеФормыДерево, ДанныеФормыЭлементДерева) в вариантах на клиенте и на сервере

Практика программирования v8 v8::УФ 1cv8.cf Бесплатно (free)

1С при интерактивном копировании строки дерева значений в управляемой форме копирует только саму строку, без его всех вложенных узлов/строк, жаль - решим! А также найдем способ передачи ДанныеФормыЭлементДерева с клиента на сервер при вставке дерева из другого элемента справочника.

11.01.2021    721    SizovE    0    

Использование программных перечислений, ч.1: строковые константы Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    38904    unichkin    74    

Ускоряем медленный/долгий и тормозной стандартный поиск по динамическому списку, настраиваем его под себя

Практика программирования Универсальные функции v8 v8::УФ 1cv8.cf Бесплатно (free)

Пользователи привыкли искать на форме списка, но, вбивая в поиск некорректные данные, могут завесить всю систему, а если еще искать нужно по НЕ полям списка, то решение только в своём поиске - все это решим в публикации с открытым кодом.

14.12.2020    9707    SizovE    2    

Программное условное оформление динамического списка, раскраска строк списка по цветам справочника или любым другим условиям (условное оформление)

Практика программирования Универсальные функции Работа с интерфейсом v8 v8::УФ 1cv8.cf Бесплатно (free)

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

30.11.2020    3245    SizovE    3    

Выгрузка HTML описаний с картинками (Base64) товаров на сайт/интернет-магазин/B2B, разберем регулярное выражение получения тега body, ПолучитьHTML, ФорматированныйДокумент

Практика программирования WEB Универсальные функции v8 v8::УФ 1cv8.cf Бесплатно (free)

Редактор HTML платформы 1С простой и очень удобный для небольших задач, однако ПолучитьHTML возвращает отдельно картинки и отдельно целиком HTML страницу со ссылкой на имена этих картинок, что неудобно для отправки в базу данных сайта/интернет-магазина/веб-приложения/B2B. Разберем на открытом коде, как решить эту проблему, напишем универсальную функцию получения значения любого тега HTML на регулярных выражениях. Бонусом - возможность редактировать теги HTML в текстовом режиме.

24.11.2020    786    SizovE    4    

Вспомогательные инструкции в коде 1С Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    32688    tormozit    105    

Установка отбора для поля ввода управляемой формы через ПараметрыВыбора (без переопределения событий "НачалоВыбора", "Автоподбор")

Практика программирования v8 v8::УФ Бесплатно (free)

Зачастую возникает необходимость ограничить вывод элементов какого-нибудь справочника или перечисления при редактировании поля ввода (отфильтровать доступные для выбора элементы) эта публикация показывает простой и эффективный способ реализации этого.

15.11.2020    4027    Eugen-S    9    

Установка нескольких фильтров/отбора СКД в табличной форме, хранение в табличной части для отправки push/email уведомлений (ОтборКомпоновкиДанных, КомпоновщикНастроек, ДинамическийСписок)

Работа с интерфейсом Практика программирования v8 v8::УФ v8::СКД Бесплатно (free)

Рассмотрим, как организовать установку фильтров/отбора СКД (динамического списка) на push/email уведомления в подсистеме EDIbot (WebApp) для 1С в табличной части "События уведомлений".

02.11.2020    1080    SizovE    0    

Базовые вещи БСП, которые облегчат жизнь программисту 1С

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Россия Бесплатно (free)

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

30.08.2020    12718    quazare    34    

Оформление и рефакторинг сложных логических выражений Промо

Практика программирования v8 Россия Бесплатно (free)

В сложных логических выражениях нередко самому автору спустя какое-то время тяжело разобраться, не говоря уже о других программистах. Предлагаемая методика позволяет повысить наглядность таких выражений путем оформления в виде И-ИЛИ дерева и одновременно выполнять их рефакторинг.

20.09.2012    79794    tormozit    131    

Использование флажков в динамических списках

Практика программирования Работа с интерфейсом v8::УФ Бесплатно (free)

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

04.08.2020    6546    nekit_rdx    28    

Использование ПоказатьВопрос() в событии НачалоВыбора()

Практика программирования v8 v8::УФ Бесплатно (free)

На ИТС описано, как избегать использования модальности в событиях ПередЗаписью() и ПередЗакрытием() (можно ознакомиться по ссылке http://its.1c.ru/docs/v8nonmodal/). А что делать, если нужно задать вопрос пользователю в событии НачалоВыбора(). В данной статье приведу пример реализации с использованием асинхронного вызова ПоказатьВопрос(). Статья предназначена в основном для начинающих программистов, недавно столкнувшихся с управляемыми формами.

20.07.2020    1772    biimmap    2    

Открытие управляемой формы 1С 8.3 с измененным несохраненным объектом

Практика программирования v8::УФ 1cv8.cf Бесплатно (free)

Как загрузить в управляемую форму программно изменённый несохранённый документ (или элемент справочника).

13.07.2020    3483    plainer    11    

Запись значения в поле ввода/формы со срабатыванием события ПриИзменении Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Иногда возникает необходимость после записи значения в какое либо поле ввода/формы вызвать для него обработчик события ПриИзменении, а о вызове самого события приходится только мечтать. В этой статье приводится программный способ вызова этого события.

11.07.2007    50731    tormozit    49    

Серверные вызовы, которые нельзя вызывать

Практика программирования v8 v8::УФ 1cv8.cf Бесплатно (free)

Не баян, а классика. Рассмотрим особенность платформы настолько же древнюю, как сами УФ.

12.05.2020    7947    SeiOkami    34    

Форма выбора (подбор) в управляемых формах

Практика программирования v8 v8::УФ 1cv8.cf Россия Бесплатно (free)

Разбор небольших примеров того, как правильно открывать форму выбора (подбора) в управляемых формах, не прибегая к модальным окнам.

08.05.2020    42724    user5300    17    

Как ограничить поля отбора в динамическом списке и ничего не сломать

Практика программирования v8::УФ 1cv8.cf Бесплатно (free)

С чем разработчик может столкнуться при попытке установки ограничений в динамическом списке.

06.05.2020    6731    SeiOkami    3    

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    47588    tormozit    74    

5 шагов по изменению резервирования товаров в УТ 11.4

Оптовая торговля Практика программирования v8::ОУ v8::УФ УТ11 Россия УУ Бесплатно (free)

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

19.03.2020    5158    Igorro82IT    16    

Об обновлениях

Практика программирования v8 v8::УФ Бесплатно (free)

Рассматриваются вопросы комментирования доработок стандартных конфигураций, необходимых для облегчения работы при обновлении конфигурации.

12.02.2020    2740    ipoloskov    27    

Детектор завершения согласования для 1С: Документооборот КОРП

Практика программирования Документооборот и делопроизводство v8::УФ ДО УУ Бесплатно (free)

Детектор, обнаруживающий завершение согласования и создающий соответствующее бизнес-событие, на которое можно настроить обработчик или автозапуск процесса.

04.02.2020    3439    shiaju    3    

Выгрузка документа по условию Промо

Практика программирования Разработка v8 Бесплатно (free)

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    16627    m-rv    2    

Программная работа с настройками СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Нюансы программной работы с настройками системы компоновки данных в отчетах и динамических списках. Обзор всех видов настроек компоновки. Что в каких случаях правильно применять. В качестве примера рассмотрена работа с отборами и группировками.

27.01.2020    43806    ids79    26    

Как вывести итоговый вес и объем на форму документа Заказ клиента. УТ 11.4

Практика программирования v8::УФ УТ11 Россия УУ Бесплатно (free)

Всем привет, долго ломал голову, но с помощью тыка и подсказок более опытных программистов, вот что мне удалось достичь и как это я сделал. Открываем конфигуратор - заходим в Документы-Заказ-Клиенту-Формы-ФормаДокумента, все будем делать только здесь, снизу формы две вкладки, в общем сама форма и модуль (как открыть, смотри рисунок - открыть форму).

16.01.2020    5699    VID1234    6    

[СКД] Программное создание схемы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Сделаем отчет на СКД полностью программно, без использования макета "схема компоновки данных".

15.01.2020    32793    John_d    22    

Как прикрутить ГУИД к регистру сведений Промо

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 Бесплатно (free)

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

16.04.2019    21245    m-rv    17    

Последовательности событий при проведении документа 1С. Шпаргалка + про формы + про расширения

Практика программирования v8 Россия Бесплатно (free)

Собрал информацию о событиях/подписках/расширениях в одном месте.

30.12.2019    25303    kuzyara    38    

Как работают управляемые формы и тонкий клиент 1С – взгляд "из-под капота"

Практика программирования Инструментарий разработчика v8::УФ Бесплатно (free)

Переход на управляемые формы перевернул процесс разработки на 1С, заставив программистов менять привычные подходы к описанию логики работы интерфейса. Руководитель компании «Цифровой Кот» Юрий Лазаренко в своем докладе на конференции Infostart Event 2019 Inception рассказал о том, как устроены управляемые формы и как правильно работать с тонким клиентом платформы 1С:Предприятие.

23.12.2019    15218    TitanLuchs    23    

30 задач. Странных и не очень

Практика программирования v8 Бесплатно (free)

30 задач на знание языка программирования 1С и некоторого поведения платформы. Маленьких. Странных и не очень.

02.12.2019    19718    YPermitin    60    

Как сделать запрос на изменение данных Промо

Практика программирования v8 v8::Запросы 1cv8.cf Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    33064    m-rv    22    

Как передать IP адрес, который вызвал HTTP запрос в 1C (для веб-сервера Apache)

Практика программирования v8 Бесплатно (free)

Столкнулся с задачей получения IP адреса, который вызывает http сервис 1С. Итак, решение:

22.11.2019    10265    Sibars    19    

Простейший пример создания бизнес-процессов

Практика программирования Управление бизнес-процессами (BPM) v8::Бизнес-процессы 1cv8.cf Бесплатно (free)

Простой пример создания бизнес-процессов в несколько шагов. Может пригодиться при первом знакомстве с ними или для решении задач экзамена 1С:Специалист по платформе.

20.11.2019    23533    YPermitin    19    

Изменение макета в карточке номенклатуры(УТ 11, КА 2)

Практика программирования Работа с интерфейсом v8::УФ ERP2 УТ11 КА2 Бесплатно (free)

Краткая памятка по выведению добавленного реквизита в справочнике Номенклатура в стандартную карточку номенклатуры в УТ 11, КА 2, ERP 2.

24.10.2019    5048    darkultro37    4    

Метод формирования движений в типовых регистрах нетиповыми регистраторами Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    29037    itriot11    34    

Полезные процедуры и функции для программиста

Практика программирования Универсальные функции v8 1cv8.cf Россия Бесплатно (free)

Все мы пишем программный код и часто используем процедуры, облегчающие его написание. Ниже приведена выборка таких полезных процедур и функций.

07.10.2019    34360    HostHost    41    

Таблица значений. Нюансы

Практика программирования v8 Бесплатно (free)

Обзор некоторых аспектов использования общеизвестного инструмента 1С.

01.10.2019    42925    Yashazz    50    

СКД. Отчеты с картинками

Практика программирования Работа с интерфейсом v8::СКД 1cv8.cf Бесплатно (free)

Решение популярных кейсов с картинками в отчетах на СКД.

25.09.2019    26400    YPermitin    41    

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    79136    Serginio    113    

"Вы всё сломали!". Разбираемся, кто прав, кто виноват

Практика программирования v8::УФ ИТ-компания Россия Бесплатно (free)

О том, как "всё испортил" программист, а на самом деле виноват заказчик.

20.09.2019    6175    RomanCrow13    27    

СКД не только для отчетов

Практика программирования v8::СКД 1cv8.cf Бесплатно (free)

СКД позволяет получать данные из информационной базы не только для вывода в отчеты, но и для других целей. Пример такого использования рассматривается в настоящей статье.

18.09.2019    20608    YPermitin    36    

Оповещения боту из 1С за 31 минуту

Практика программирования Интеграция v8::УФ 1cv8.cf Бесплатно (free)

Поделюсь опытом, как быстро сделать бота с оповещениями в Телеграмм из 1С без лишних затрат.

18.09.2019    18569    feva    42    

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С Промо

Математика и алгоритмы Практика программирования v8 v8::blocking 1cv8.cf Бесплатно (free)

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    38744    ids79    40    

[Шпаргалка] Программное создание элементов формы

Практика программирования Работа с интерфейсом v8 1cv8.cf Бесплатно (free)

Программное создание практически всех популярных элементов формы.

06.09.2019    73403    rpgshnik    70    

Агрегатные функции СКД, о которых мало кто знает

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    61569    ids79    55