Пример реализации обмена с оборудованием через 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 309 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 309 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 309 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 309 12.01.17 19:39 Сейчас в теме
(1) Антон, прошу прощения за невнимательность.
Вы имели в виду мою неточность в описании, точнее некорректное построение фразы:

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

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

GetInterfaceSafetyOptions, SetInterfaceSafetyOptions

ну естественно под win
6. Darklight 24 12.01.17 14:33 Сейчас в теме
Большое списбо за статью, познавательно!
Сам храню COM-объекты через модули повторного использования - тоже ретушируются (без упаковки в структуру; как возвращаемые значения), но есть свои неудобства такого подхода.
Но технология COM - это уже прошлый век.
Что же делать под Linux?
10. asdfgcom 309 12.01.17 18:04 Сейчас в теме
(6) Как говорится, спасибо за спасибо.
Что Вы подразумевали под: "Что же делать под Linux?"
COMобъекты может и устарели, но с ними легко быстро не зная ничего кроме 1С и протокола или описания методов начать работать над задачей.
К данной работе я подходил около месяца. Пытался сначала "врапить" по технологии NET, однако знаний не хватало и времени. По протоколу через winsocket надоумил сам производитель оборудования. Уже через неделю описал все команды, через 3 недели готовый прототип обмена. Сейчас "пилю" интерфейс, засовываю в расширение (для этого и понадобились параметры сеанса). К сожалению придется добавлять регистр сведений, синхронизировать его с данными из контроллера.
11. Darklight 24 12.01.17 18:16 Сейчас в теме
(10)Как работать сокeтами под Linux
12. asdfgcom 309 12.01.17 18:30 Сейчас в теме
(11) 1С у заказчика под Windows. Однако, в свете последних событий и импортозамещения, придется скоро осваивать не только сокеты под Linux.
14. asdfgcom 309 28.01.17 12:23 Сейчас в теме
В данный момент отказались от использования WinSocket и работой с контроллером непосредственно из 1С. 1С работает с контроллером очень медленно. На "слабых" машинах приходится полностью отключать автоматический опрос, т.к. обработчики событий начинают подавать команды не по очереди, а одновременно из-за медленной обработки событий и задач. Создавать кэш команд не хочется, решили всю низкую часть перенести на java.
Однако, для простых запросов вышеописанный способ общения может пригодиться.
15. vdenu 01.03.17 17:21 Сейчас в теме
Спасибо за статью, но вероятно я невнимательно её изучил и так и не понял два вопроса:
1. Каким же образом COM-объект созданный на сервере и затем помещённый в структуре во Временное хранилище может стать доступным на стороне клиента? ПолучитьИзВременногоХранилища() не срабатывает со стандартной ошибкой "Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа" Т.е. программа знает, что в структуре я "спрятал" com
2. Если я создаю Винсокет на стороне сервере, то как использовать ДобавитьОбработчик?
16. asdfgcom 309 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 309 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 309 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 309 02.03.17 14:57 Сейчас в теме
(20) У меня браузер Chrome. Иногда (не всегда) после нажатия на </> не открывается форма вставки кода, а появляется то же окно редактирования сообщения, только без набранного текста. Не разобрался пока в чем дело.
22. vdenu 02.03.17 15:10 Сейчас в теме
Евгений, я недостаточно точно выразился. Вот ваша цитата: "Как же его хранить? Будем хранить его в параметрах сеанса. Оттуда он доступен и клиенту и серверу. " Хранить в структуре его (ComОбъект) можно, но доступен он всегда только для сервера и никогда для клиента. (Соответственно в случае с winsocket подобное решение лишено смысла)
23. asdfgcom 309 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: строковые константы Промо

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

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

10.12.2016    37865    unichkin    74    

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

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

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

30.11.2020    944    SizovE    0    

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

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

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

24.11.2020    366    SizovE    0    

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

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

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

15.11.2020    2800    Eugen-S    9    

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

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

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

15.10.2018    31089    tormozit    104    

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

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

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

02.11.2020    677    SizovE    0    

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

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

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

04.08.2020    3728    nekit_rdx    24    

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

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

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

20.07.2020    1499    biimmap    2    

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

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

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

20.09.2012    78564    tormozit    131    

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

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

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

13.07.2020    3190    plainer    11    

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

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

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

12.05.2020    6632    SeiOkami    31    

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

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

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

08.05.2020    26088    user5300    16    

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

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

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

11.07.2007    49148    tormozit    48    

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

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

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

06.05.2020    5345    SeiOkami    3    

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

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

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

19.03.2020    4723    Igorro82IT    16    

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

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

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

12.02.2020    2662    ipoloskov    27    

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

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

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

10.09.2017    45602    tormozit    74    

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

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

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

04.02.2020    3140    shiaju    3    

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

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

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

27.01.2020    31331    ids79    26    

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

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

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

16.01.2020    4521    VID1234    6    

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

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

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

25.04.2019    16221    m-rv    2    

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

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

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

15.01.2020    26819    John_d    22    

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

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

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

23.12.2019    13377    TitanLuchs    23    

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

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

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

24.10.2019    4615    darkultro37    4    

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

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

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

16.04.2019    20629    m-rv    17    

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

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

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

07.10.2019    31118    HostHost    40    

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

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

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

01.10.2019    36084    Yashazz    50    

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

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

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

25.09.2019    22821    YPermitin    40    

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

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

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

01.06.2018    31393    m-rv    21    

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

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

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

20.09.2019    6046    RomanCrow13    27    

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

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

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

18.09.2019    17535    feva    42    

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

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

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

06.09.2019    56623    rpgshnik    65    

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

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

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

05.12.2017    28530    itriot11    34    

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

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

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

05.09.2019    53145    ids79    54    

EnterpriseData – часть 3. Загрузка данных, идентификация объектов

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

Основные этапы загрузки данных через EnterpriseData. Идентификация объектов загружаемых полностью и по ссылке. Приведены схемы процессов загрузки данных. Описание основных операций и обработчиков. Перечень процедур БСП, используемых при загрузке данных, структура «КомпонентыОбмена».

22.08.2019    15579    ids79    8    

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив

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

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    92897    ids79    56    

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

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

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

27.01.2016    77273    Serginio    110    

Кодовое создание документа на 8.3, управляемые формы (на примере)

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

В своё время мне нужен был код создания документа через обработку, пол дня потерял пока нашёл гайд по решению данной задачи. Поэтому просто решил поделиться данным решением. Подойдёт только новичкам, опытные программисты могут даже не читать =)

07.08.2019    6206    Nefilimus    16    

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты

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

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    66494    ids79    12    

Создание отчетов с помощью СКД - основные понятия и элементы

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

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    55917    ids79    26    

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

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

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

10.11.2018    35845    ids79    40    

Вставка гиперссылки в форматированный документ

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

Да, форматированный документ это умеет и сам, но возможности можно расширить!

03.06.2019    6546    Yashazz    0    

Добавление внешних отчетов / обработок в собственные подсистемы

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

Краткая инструкция по добавлению функционала доп обработок/отчетов в собственную подсистему.

24.05.2019    11815    login1020    7    

Расшифровка отчета на СКД с детализацией по выбранному полю на основе БСП

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

В данной статье рассмотрим механизм работы с расшифровкой отчета, созданного при помощи системы компоновки данных, в управляемом приложении. Показывать буду на примере реальной задачи. Условие: использовать имеющиеся в конфигурации механизмы БСП, с минимальными и "правильными" изменениями. Расшифровка должны быть двух видов на каждом поле: 1. Открывать ссылочный объект 2. Открывать новую форму с детализацией табличной части документа. Собственно ради второго пункта и писалась статья, в основном для себя, чтобы не забыть.

14.05.2019    20797    Viktor_Ermakov    8    

Тестер: частые вопросы Промо

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

Ошибкам бой - тесты норма жизни!

25.07.2018    29630    grumagargler    28    

Оперативная доработка отчетов без обновления конфигурации или расширения

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

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

12.05.2019    4648    samvani    0    

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

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

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

18.04.2019    3693    NeSPEC    0    

Этюды по программированию. Хитрости создания расширений для конфигураций на БСП. Часть 2

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

Некоторые нюансы, если вы захотите создавать свои расширения. Продолжение первой части.

16.04.2019    11205    milkers    9    

Ускоряем 1С: модули с повторным использованием возвращаемых значений Промо

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

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

04.09.2017    53676    m-rv    61    

О расширениях замолвите слово...

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

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    36371    ellavs    126    

Git-репозитории для 1С-кода (опыт использования при небольших проектах)

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

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

28.03.2019    27920    ellavs    90