Max: Исключение повторных нажатий кнопок до ответа сервера

Как бы не ругались некоторые товарищи на Habr, что «разрабатывать под Max, себя не уважать», но тем не менее не все имеют этот выбор 😉 Так что проблемы решать таки нужно..

Итак, задача: между нажатием кнопки с кэлбеком и ответом сервера происходит некоторая пауза. Иногда в несколько секунд. Пользователи не всегда дожидаются ответа, и нажимают кнопки по нескольку раз.

Решение: т.к. на основной ответ сервера требуется некоторое время на его подготовку, то перед «настоящим» ответом сервера, отправим «промежуточный», который сообщит пользователю «Подождите ответа сервера», а заодно скроет все кнопки из предыдущего сообщения пользователя, чтоб не было соблазна их нажимать. Код получается примерно такой:

...
    if (isset($in->update_type)){
        if ($in->update_type=="message_callback"){
          $params=[];
          $params["callback_id"]=$in->callback->callback_id;
          $data=[];
          $data["message"]["attachments"]=[];
          $data["notification"]="Подождите ответа сервера...";
          $res=$Max->Reqwest("answers",$params,$data,"POST");    
        };
        if (($in->update_type=="message_created") or ($in->update_type=="message_callback") or ($in->update_type=="bot_started")){                       
          $res=$Api1c->reqwest("MaxCallback2",["body"=>$body]);  // пересылаем всё что пришло в 1С  и получаем ответ
          if ($res==null){
            $params=[];  
            $params["chat_id"]=$in->message->recipient->chat_id;
            $data=[];
            $data["text"]="Временная ошибка серверера. Попробуйте позже.";    
            $data["format"]= "html";            
                $buttons=[];                
                    $button=[];
                    $button["type"]="callback";
                    $button["text"]="Перейти в главное меню";
                    $button["payload"]="Go2MainMenu";                
                $buttons[]=$button;                                
                    $attachment=[];
                    $attachment["type"]="inline_keyboard";
                    $attachment["payload"]["buttons"]=[];
                    $attachment["payload"]["buttons"][]=$buttons;                                                     
            $data["attachments"]=[];    
            $data["attachments"][]=$attachment;
            $res=$Max->Reqwest("messages",$params,$data,"POST");    
            die();  
          };
    // если 1С вернула ошибку то её и показываем пользователю
          if ($res->error==true){
            $params=[];  
            if (isset($in->message)){$params["chat_id"]=$in->message->recipient->chat_id;};
            if (isset($in->chat_id)){$params["chat_id"]=$in->chat_id;};        
            $data=[];
            $data["text"]=$res->result;    
            $data["format"]= "html";            
                $buttons=[];                
                    $button=[];
                    $button["type"]="callback";
                    $button["text"]="Перейти в главное меню";
                    $button["payload"]="Go2MainMenu";                
                $buttons[]=$button;                                
                    $attachment=[];
                    $attachment["type"]="inline_keyboard";
                    $attachment["payload"]["buttons"]=[];
                    $attachment["payload"]["buttons"][]=$buttons;                                                     
            $data["attachments"]=[];    
            $data["attachments"][]=$attachment;
            
            $res=$Max->Reqwest("messages",$params,$data,"POST");          
            die();  
          };
          // Что пришло из 1С, то и отдаём в сообщения пользователю..
          $params=$res->result->params;
          $data=$res->result->data;
          $res=$Max->Reqwest("messages",$params,$data,"POST");          
          die();
...

Нашел свою первую «домашнюю страничку»

В бытность еще свою на narod.ru. Может кто и помнит, был тогда аттракцион невиданной щедрости, когда была возможность при помощи конструктора сделать свой простенький бложик со своим доменным именем. Вот и у меня году в 2004 такой был: donpadlo.narod.ru К сожалению спустя 22 года, от него остались рожки на ножки.. И даже не открывается. Единственно что нашел, «сохраненная копия» гостевой книги:

P.S. Не забыть бы, написать снова мемуары про службу в армии и воинскую часть в Баковке 74213.

P.P.S. В архиве интернета пока доступна.. Жаль фоточек там не сохранилось https://web.archive.org/web/20040813233634/http://www.donpadlo.narod.ru

P.P.P.S: Часть писанины с того сайта перенес на этот в «самое начало», «Задней датой»

1С: Поиск в списке выбора

Вообще поиск в списке выбора уже в 1С реализован штатно. Но! как всегда со своими нюансами (видимо в угоду универсальности). А именно: поиск ведется только по началу строки. Если же хочется чтоб поиск был более «умный». то можно навесить на событие «АвтоПодбор» свою реализацию. Например такую:

&НаКлиенте
Процедура ШаблонДокументаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	
	Результат=Новый СписокЗначений();
	для каждого стр из Элементы.ШаблонДокумента.СписокВыбора цикл
		если СтрНайти(ВРег(Строка(стр.Представление)),ВРег(Текст))<>0 тогда
			Результат.Добавить(стр.Значение,стр.Представление,стр.Пометка,стр.Картинка);
		конецесли;
	конеццикла;	
	ДанныеВыбора=Результат;
	СтандартнаяОбработка = Ложь;
	
КонецПроцедуры

1С: Вычисляемые поля в СКД

Избегаю делать отчеты через СКД, потому что спустя какое-то время, сложный отчет превращается в жуткую абракадабру, в которой потом разобраться очень трудно. Слишком всё запутано, слишком много галочек, настроек и прочего. Да, можно сделать почти всё, но для этого нужно СКД знать досконально, и пользоваться им каждый день, чтобы не забыть все нюансы. Когда же сам пишешь отчет, а не через СКД, то тут и комментарии доложишь, и логику попроще сделаешь (пусть и в ущерб производительности). Вот и сейчас, пришлось покопаться в СКД, чтобы вспомнить, как например сделать трюк, с размещением периода дат в одной ячейке. Типа вот так:

Ну а реализация на самом деле простая вышла:

1С: Проверка на пустое значение в запросе

На самом деле это не так просто сделать. Есть несколько вариантов, для разных типов значений:

  • Дата: СК_ИскВходящий.ДатаВступленияРешенияВСилу = ДАТАВРЕМЯ(1, 1, 1)
  • Если тип значения не составной, то: Аппеляция.ВидОбжалования ЕСТЬ NULL
  • А вот с составным весело — почему то сравнение с NULL не работает в этом случае. Приходится использовать сравнение типов. Как-то так у меня вышло:
ВЫБОР
	КОГДА СК_ИскВходящий.Обжалование = ЛОЖЬ
			И (ТИПЗНАЧЕНИЯ(СК_ИскВходящий.ИтоговыйСудебныйАкт) <> ТИП(СТРОКА)
				И ТИПЗНАЧЕНИЯ(СК_ИскВходящий.ИтоговыйСудебныйАкт) <> ТИП(Перечисление.СК_ГР_ИтоговыйСудебныйАкт))
		ТОГДА "Находится на рассмотрении в суде первой инстанции"
	КОГДА СК_ИскВходящий.Обжалование = ЛОЖЬ
			И СК_ИскВходящий.ДатаВступленияРешенияВСилу = ДАТАВРЕМЯ(1, 1, 1)
			И СК_ИскВходящий.ДатаСудебногоАкта > ДАТАВРЕМЯ(1, 1, 1)
			И СК_ИскВходящий.ИтоговыйСудебныйАкт = ЗНАЧЕНИЕ(Перечисление.СК_ГР_ИтоговыйСудебныйАкт.РешениеОбУдовлетворенииТребований)
		ТОГДА "Вынесен судебный акт, не вступил в законную силу"
	КОГДА СК_ИскВходящий.Обжалование = ИСТИНА
			И НЕ Аппеляция.ВидОбжалования ЕСТЬ NULL
			И СК_ИскВходящий.ИтоговыйСудебныйАкт = ЗНАЧЕНИЕ(Перечисление.СК_ГР_ИтоговыйСудебныйАкт.РешениеОбУдовлетворенииТребований)
			И СК_ИскВходящий.ДатаСудебногоАкта > ДАТАВРЕМЯ(1, 1, 1)
			И СК_ИскВходящий.ДатаВступленияРешенияВСилу = ДАТАВРЕМЯ(1, 1, 1)
		ТОГДА "Вынесен судебный акт, обжалуется в апелляционной инстанции"
	КОГДА ТИПЗНАЧЕНИЯ(СК_ИскВходящий.ИтоговыйСудебныйАкт) <> ТИП(СТРОКА)
			И ТИПЗНАЧЕНИЯ(СК_ИскВходящий.ИтоговыйСудебныйАкт) <> ТИП(Перечисление.СК_ГР_ИтоговыйСудебныйАкт)
			И СК_ИскВходящий.ДатаСудебногоАкта > ДАТАВРЕМЯ(1, 1, 1)
			И СК_ИскВходящий.ДатаВступленияРешенияВСилу > ДАТАВРЕМЯ(1, 1, 1)
			И НЕ Кассация.ВидОбжалования ЕСТЬ NULL
			И РАЗНОСТЬДАТ(&ТекДата, СК_ИскВходящий.ДатаСудебногоАкта, МЕСЯЦ) < 3
		ТОГДА "Судебный акт вступил в законную силу, но не вышел срок для кассационного обжалования"
	КОГДА СК_ИскВходящий.ИтоговыйСудебныйАкт = ЗНАЧЕНИЕ(Перечисление.СК_ГР_ИтоговыйСудебныйАкт.РешениеОбУдовлетворенииТребований)
			И СК_ИскВходящий.ДатаСудебногоАкта > ДАТАВРЕМЯ(1, 1, 1)
			И СК_ИскВходящий.ДатаВступленияРешенияВСилу = ДАТАВРЕМЯ(1, 1, 1)
			И НЕ Кассация.ВидОбжалования ЕСТЬ NULL
			И Кассация2Инстанция.ДатаВозвратаИзСуда = ДАТАВРЕМЯ(1, 1, 1)
		ТОГДА "Вынесен судебный акт, обжалуется в кассационной инстанции"
	ИНАЧЕ "Неопределено"
КОНЕЦ

Тут в принципе можно подсмотреть все варианты

1 2 3 319