Каталог решений - Мелкие полезные функции

Мелкие полезные функции

Мелкие полезные функции

В наличии

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

Категория:

Описание

1. Получение объекта по идентификатору.

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

// Возвращает ссылку на найденный справочник или документ или Неопределено, если объекта нет.
// Параметры
// ИД - строковое представления уникального идентификатора
// Тип - наименование вида справочника или документа. Благо их наименования не пересекаются.
Функция ПолучитьСсылкуПоИД(ИД, Тип = Неопределено)
	Если ИД = "" и Тип <> Неопределено Тогда
		// Тип известен, элемент явно пустой, значит нужно вернуть пустую ссылку
		спр = Метаданные.Справочники.Найти(Тип);
		Если спр <> Неопределено Тогда
			Возврат Справочники[Тип].ПустаяСсылка();
		КонецЕсли;
		
		док = Метаданные.Документы.Найти(Тип);
		Если док <> Неопределено Тогда
			Возврат Документы[Тип].ПустаяСсылка();
		КонецЕсли;
		Возврат Неопределено
	КонецЕсли;
	
	Попытка
		УИД = Новый УникальныйИдентификатор(ИД);
	Исключение
		Возврат Неопределено
	КонецПопытки;
	
	// Если тип известен, то ищем только в одной таблице
	Если Тип <> Неопределено Тогда
		спр = Метаданные.Справочники.Найти(Тип);
		Если спр <> Неопределено Тогда
			Ссылка = Справочники[Тип].ПолучитьСсылку(УИД);
			Если Не Ссылка.Пустая() и Ссылка.ПолучитьОбъект() <> Неопределено Тогда
				Возврат Ссылка
			КонецЕсли;
			Возврат Неопределено
		КонецЕсли;
		
		док = Метаданные.Документы.Найти(Тип);
		Если док <> Неопределено Тогда
			Ссылка = Документы[Тип].ПолучитьСсылку(УИД);
			Если Не Ссылка.Пустая() и Ссылка.ПолучитьОбъект() <> Неопределено Тогда
				Возврат Ссылка
			КонецЕсли;
		КонецЕсли;
		Возврат Неопределено
	КонецЕсли;
	
	// Если тип неизвестен, то перебираем все справочники и документы.
	// Это долго. Поэтому тип очень хочется получить.
	Для Каждого спр из Метаданные.Справочники Цикл
		Ссылка = Справочники[спр.Имя].ПолучитьСсылку(УИД);
		Если Ссылка.ПолучитьОбъект() <> Неопределено Тогда
			Возврат Ссылка
		КонецЕсли;
	КонецЦикла;
	
	Для Каждого док из Метаданные.Документы Цикл
		Ссылка = Документы[док.Имя].ПолучитьСсылку(УИД);
		Если Ссылка.ПолучитьОбъект() <> Неопределено Тогда
			Возврат Ссылка
		КонецЕсли;
	КонецЦикла;
	
	Возврат Неопределено
КонецФункции

 

2. Разрешение пользователям редактировать отдельные реквизиты документа без перепроведения или просто одни реквизиты разрешать, а другие запрещать.

Иногда необходимо разрешить редактирование некоторых реквизитов документа без перепроведения. Например: Комментарий, АдресКонтрагента, КонтактноеЛицо. Ещё бывает необходимым разрешить изменение отдельных реквизитов в закрытых документах. Например, поставить отметку о состоянии доставки и написать комментарий.

В модуле менеджера документа пишем функцию, которая определяет массив допустимых к редактированию реквизитов

// Возвращает массив имён реквизитов, разрешённых для изменнения без перепроведения.
// Если получен параметр типа Массив, то имена реквизитов добавляются в него
Функция ПолучитьМассивРеквизитовИзменяемыхБезПерепроведения(МассивРеквизитовДопустимыхКИзменению =  Неопределено) Экспорт
	Если Не ТипЗнч(МассивРеквизитовДопустимыхКИзменению) = Тип("Массив") Тогда
		МассивРеквизитовДопустимыхКИзменению = Новый Массив;
	КонецЕсли;
	//Типовые реквизиты
	МассивРеквизитовДопустимыхКИзменению.Добавить("Грузополучатель");
	МассивРеквизитовДопустимыхКИзменению.Добавить("ДоверенностьНомер");
	МассивРеквизитовДопустимыхКИзменению.Добавить("ДоверенностьДата");
	МассивРеквизитовДопустимыхКИзменению.Добавить("ДоверенностьНомер");
	МассивРеквизитовДопустимыхКИзменению.Добавить("ДоверенностьВыдана");
	МассивРеквизитовДопустимыхКИзменению.Добавить("ДоверенностьЧерезКого");
	МассивРеквизитовДопустимыхКИзменению.Добавить("Комментарий");
	МассивРеквизитовДопустимыхКИзменению.Добавить("АдресДоставки");
	//Добавленные реквизиты
	
	Возврат МассивРеквизитовДопустимыхКИзменению;
КонецФункции

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

// сравниваем реквизиты документа из базы данных с записываемым объектом
// имена изменённых реквизитов запихываем в массив
Функция ПолучитьСписокИзменённыхРеквизитов(ДокОбъект) Экспорт
	СписокИзменённыхРеквизитов = Новый Массив;
	
	Ссылка = ДокОбъект.Ссылка;
	мдОбъекта = ДокОбъект.Метаданные();
	// сравниваем стандартные реквизиты
	Для Каждого Реквизит из мдОбъекта.СтандартныеРеквизиты Цикл
		Если ДокОбъект[Реквизит.Имя] <> Ссылка[Реквизит.Имя] Тогда
			СписокИзменённыхРеквизитов.Добавить(Реквизит.Имя);
		КонецЕсли;
	КонецЦикла;
	
	// сравниваем реквизиты шапки
	Для Каждого Реквизит из мдОбъекта.Реквизиты Цикл
		Если ДокОбъект[Реквизит.Имя] <> Ссылка[Реквизит.Имя] Тогда
			СписокИзменённыхРеквизитов.Добавить(Реквизит.Имя);
		КонецЕсли;
	КонецЦикла;
	
	// сравниваем табличные части
	Для Каждого тч из мдОбъекта.ТабличныеЧасти Цикл
		Если ДокОбъект[тч.Имя].Количество() = Ссылка[тч.Имя].Количество() Тогда // Не добавляли и не убирали строки в тч
			Для Каждого строкаОбъекта Из ДокОбъект[тч.Имя] Цикл
				СтрокаСсылки = Ссылка[тч.Имя].Получить(строкаОбъекта.НомерСтроки - 1);
				Для Каждого Реквизит из тч.Реквизиты Цикл
					Если СтрокаСсылки[Реквизит.Имя] <> строкаОбъекта[Реквизит.Имя] Тогда
						СписокИзменённыхРеквизитов.Добавить(тч.Имя + "." + Реквизит.Имя);
					КонецЕсли;
				КонецЦикла;
			КонецЦикла;
		Иначе
			СписокИзменённыхРеквизитов.Добавить(тч.Имя);
		КонецЕсли;
	КонецЦикла;
	
	Возврат СписокИзменённыхРеквизитов;
КонецФункции

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

В модуле документа ПредЗаписью разрешаем запись без пререпроведения в случае, если были изменены только реквизиты, не вызывающие перепроведение.

РедактированиеЗаднимЧислом = Ложь;
МассивРеквизитовДопустимыхКИзменению = Документы.РеализацияТоваровУслуг.ПолучитьМассивРеквизитовИзменяемыхБезПерепроведения();
СписокИзменённыхРеквизитов = ОбщегоНазначения.ПолучитьСписокИзменённыхРеквизитов(ЭтотОбъект);
СписокИзменённыхРеквизитовВызывающихПерепроведение = ОбщегоНазначения.МожноЗаписыватьБезПерепроведения(ЭтотОбъект, МассивРеквизитовДопустимыхКИзменению, СписокИзменённыхРеквизитов);
Если СписокИзменённыхРеквизитовВызывающихПерепроведение = "" И Проведен И СписокИзменённыхРеквизитов.Количество() > 0 Тогда
	РежимЗаписи = РежимЗаписиДокумента.Запись;
ИначеЕсли НЕ РедактированиеЗаднимЧислом и Дата < НачалоДня(ТекущаяДата()) И Не РольДоступна("ПравоАдминистрирования") Тогда
	Сообщить("Недостаточно прав для проведения реализации " + Номер + " " + Строка(Дата) +
			" задним числом. Изменены реквизиты: " + СписокИзменённыхРеквизитовВызывающихПерепроведение);
	Отказ = Истина;
КонецЕсли;

В этой заметке не рассмотрена установка флага ТолькоПросмотр для реквизитов формы, которые нельзя редактить. Это делается сосем несложно.

Не знаю, может быть подобное решение уже есть в БСП. Не смотрел.

газета Суть Времени

has been added to your cart:
Оформление заказа