Вот и пригодилась опять теория вероятности ;)

Задача: есть два исполнителя. Необходимо обеспечить, чтобы исполнителю №1 доставалось 2/3 заявок, и исполнителю №2 — 1/3 задач.

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

  • Исполнитель 1, с долями 2/3
  • Исполнитель 2, с долями 1/3

Как вычисляем исполнителя:

Всего долей: 3

  • — Создаем кость, с гранями 1,2,3
  • — Грани 1 и 2  = Исполнитель 1
  • — Грань 3  = Исполнитель 2

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

  • Исполнитель 1:  67%
  • Исполнитель 2:  33 %

Ну и кому интересно, вот код реализации:

&НаСервере
Функция ВыбратьИсполнителяНаСервере()
	Наименование=объект.Район;
	нама=СтрРазделить(Наименование," ");
	Район=ВРег(нама[0]);
	Исполнители=Новый Массив();
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ДоступВЛКДляКонтрагентаРайоныОбслуживания.Ссылка.Ссылка КАК Ссылка,
		|	ДоступВЛКДляКонтрагентаРайоныОбслуживания.Доля КАК Доля
		|ИЗ
		|	Справочник.ДоступВЛКДляКонтрагента.РайоныОбслуживания КАК ДоступВЛКДляКонтрагентаРайоныОбслуживания
		|ГДЕ
		|	ВРЕГ(ДоступВЛКДляКонтрагентаРайоныОбслуживания.Район.Наименование) ПОДОБНО &Наименование";	
	Запрос.УстановитьПараметр("Наименование", "%"+Район+"%");	
	РезультатЗапроса = Запрос.Выполнить();	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();		
	ВсегоДолей=0;
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		Исполнители.Добавить(Новый Структура("исполнитель,доля",ВыборкаДетальныеЗаписи.Ссылка,ВыборкаДетальныеЗаписи.Доля));	
		ВсегоДолей=ВсегоДолей+ВыборкаДетальныеЗаписи.Доля;
	КонецЦикла;
	
	Если Исполнители.Количество()=0 тогда
		возврат неопределено;
	конецесли;	
	// если исполнитель один, то с долями не морочимся
	Если Исполнители.Количество()=1 тогда
		Возврат   Исполнители[0].исполнитель;
	конецесли;	
	
	// если всего долей 0, а исполнителей более чем 1, то тогда исполнитель - первый попавшийся
	если ВсегоДолей=0 тогда
		Возврат   Исполнители[0].исполнитель;
	конецесли;	
	
	
	// А вот тут уже мудрим с долями
	ЗаполненныеДоли=Новый Массив();
	для каждого исполнитель из Исполнители цикл
		для поз=1 по исполнитель.доля цикл
			ЗаполненныеДоли.Добавить(исполнитель.исполнитель);
		конеццикла	
	конеццикла;	
	
	// Здесь уже имеем массив с заполненными развернутыми исполнителями. Например: Вася,Вася,Вася,Петя,Петя
	// Осталось сгенерировать случайное число 1-5, и назначить в соответствии с выпавшим числом исполнителя
	Генератор = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
	СлучайноеЧисло = Генератор.СлучайноеЧисло(0,ЗаполненныеДоли.Количество()-1);
	Возврат ЗаполненныеДоли[СлучайноеЧисло];
		
КонецФункции

1С: Запрет запуска дубля регламентного задания

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

Решение: да простое. Просто перед запуском задания, убедимся что предыдущая копия уже отработала. Во первых, нужно у регламентного задания прописать ключ. А во вторых, непосредственно перед запуском объемной части задания, нужно проверять фоновые задания, и если задание с таким ключём в списке активных…то ничего далее не делать:

Функция ОтправитьДанныеИзПланаОбменаРегламентно()
	// проверим, а вдруг еще не завершено предыдущее регламентное задание?
	Фоновые = ФоновыеЗадания.ПолучитьФоновыеЗадания();    
    Для Каждого Фоновое из Фоновые Цикл        
        Если Найти(Фоновое.Ключ, "отправка_данных_шины") > 0 И Фоновое.Состояние = СостояниеФоновогоЗадания.Активно Тогда            
            Возврат 0;            
        КонецЕсли;                        
    КонецЦикла;	
...
КонецФункции

Открытие URL ссылки на 1с в Linux

Задача: необходимо чтобы при нажатии на URL вида: e1c://server/srv-1c/basename#e1cib/data/%D… автоматически открывалась 1С с открытым документом.

Решение: Linux открывает подобные ссылки в почте и прочих местах через утилиту xdg-open, которая в свою очередь открывает такие ссылки в т.ч. согласно ярлычкам *.desktop находящимся в  ~/.local/share/applications/. Следовательно достаточно разместить там файл с содержимым:

[Desktop Entry]
Exec=/opt/1cv8/common/1cestart /url %U
Name=1C:Enterprise x64
GenericName=1C:Enterprise x64
Terminal=false
TryExec=/opt/1cv8/common/1cestart
Type=Application
MimeType=x-scheme-handler/e1c
NoDisplay=true

И далее перечитать кэш связей протокола:

update-desktop-database ~/.local/share/applications

1С: Сброс пароля администратора в файловой БД

Рассматриваю вариант под ОС Linux. В некотором смысле это получается даже проще чем под Windows — не нужно искать никаких дополнительных утилит типа редактора HEX- всё уже есть «базе»

1) Открываем на просмотр в mc файл 1Cv8.1CD

2) Переходим в режим просмотра HEX — F4.

3) Ищем в режиме поиска в шестнадцатеричном формате сочетание 00 09 00 75 00 73

4) Заменяем 00 09 на 01 09, сохраняем изменения

5) Ищем 56 38 55 53 45 52 53 4D , заменяем 56 на 48

6) Открываем утилиту chdbfl из папки /opt/1cv8/x86_64/8.3.25.1445 (у вас папка другая конечно), и восстанавливаем базу.

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

1С: Поиск элемента справочника с одинаковыми кодами.

1С позволяет создавать элементы справочника (да и документа) с одинаковыми кодами (номерами), в этом случае поиск элемента по типичному:

 справочники.ГруппыПользователей.НайтиПоКоду("123");

Становится невозможным. Есть несколько вариантов решения данной проблемы:

1) Можно поискать по заведомо уникальному реквизиту (если есть):

 справочники.ГруппыПользователей.НайтиПоРеквизиту("Артикул","123");

2) Можно поискать по уникальному идентификатору (если известен):

доко.ТекущийЭтап=Справочники.itilprofЭтапыМаршрутов.ПолучитьСсылку(Новый УникальныйИдентификатор("149e1ab6-325f-11ec-9560-005056be733d"));

3) Можно поискать по сочетанию факторов, которые сделают элемент уникальным (в данном случае по владельцу):

ТекДок.ТекущийЭтап			= справочники.itilprofЭтапыМаршрутов.НайтиПоКоду("Регистрация",,,Справочники.itilprofМаршруты.НайтиПоНаименованию("Инцидент"));
1 2 3 4 37