1С: Событие «ПриКопировании» в регистре сведений

А вот не обрабатывает 1С такое событие в регистре сведений, поэтому одним из решений будет обработка параметров формы записи при событии «При создании на сервере». Например так:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	если ЗначениеЗаполнено(Параметры.ЗначениеКопирования.uuid) = истина тогда
		этотобъект.запись.uuid=Новый УникальныйИдентификатор();
	конецесли;	
КонецПроцедуры

Т.е. если это «копирование», то значение заполнено «старыми» данными и их можно перезаписать.

1С: Шпаргалка по работе с таблицей значений

Ниже приведены наиболее часто используемые применения. Рассматриваются наиболее часто встречающиеся операции.

Определение типа колонок:


// Ссылочные типы
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("Сотрудник", Новый ОписаниеТипов("СправочникСсылка.Сотрудники"));  
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("СчетФактура", Новый ОписаниеТипов("ДокументСсылка.СчетФактураВыданный"));
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("ТипКонтактнойИнформации", Новый ОписаниеТипов("ПеречислениеСсылка.ТипыКонтактнойИнформации"));  
 
// Простые типы
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("ДолжностьНаименование", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(150))); 
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число",, Новый КвалификаторыЧисла(10,2)));
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата",, Новый КвалификаторыДаты(ЧастиДаты.Дата)));
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("ЕстьОповещение", Новый ОписаниеТипов("Булево"));   
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("ИменаПолейСубконто", Новый ОписаниеТипов("Массив"));  

//Составное
МассивТипов = Новый Массив();
МассивТипов.Добавить(Тип("Булево"));
МассивТипов.Добавить(Тип("ПеречислениеСсылка.ВидыПродукцииИС"));	
ТЗ_ДанныеПоСотрудникам.Колонки.Добавить("МаркировкаОстатков", Новый ОписаниеТипов(МассивТипов));
     

Удаление строк:

// 1. Обходом строк
МассивКУдалению = Новый Массив;
Для Каждого ТекущаяСтрока Из ТЗ Цикл	
	Если ТекущаяСтрока.Удалить Тогда
		МассивКУдалению.Добавить(ТекущаяСтрока);
	КонецЕсли;	
КонецЦикла;
Для Каждого ТекущаяСтрока Из МассивКУдалению Цикл
	ТЗ.Удалить(ТекущаяСтрока);
КонецЦикла;
 
// 2. Найденные по отбору
НайденныеСтроки = ТЗ.НайтиСтроки(Новый Структура("Удалить", Истина));
Для Каждого ТекущаяСтрока Из НайденныеСтроки Цикл	
	ТЗ.Удалить(ТекущаяСтрока);	
КонецЦикла;
 
// 3. Выгрузка с отбором
НоваяТЗ = ТЗ.Скопировать(Новый Структура("Удалить", Ложь));

Сортировка:

ТЗДат.Сортировать("Дата Возр");

1С: Сохранение логов изменений регистра сведений

Задача: вести журнал логов изменения записей регистра сведений

Решение:

Штатного механизма как в Документа или Справочниках нет (ну собственно и правильно, т.к. запись сейчас есть, через минуту её нет). Потому разработаем собственный механизм. Общий алгоритм будет следующий:

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

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

&НаКлиенте
Перем ДанныеФормыДоИзменения;

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
	СохранитьИзмененияЕслиТаковыеЕсть(ДанныеФормыДоИзменения)
КонецПроцедуры

&НаСервере
Функция ПолучитьДанныеДоОбновления()
	ДанныеПоРегистру=Метаданные.РегистрыСведений.СГ_ГР_ТранспортныйФайлПриборыУчета;
	ДоступныеПоля=Новый Структура();
	для каждого стр из ДанныеПоРегистру.Измерения цикл
		ДоступныеПоля.Вставить(стр.имя,неопределено);
	конеццикла;	
	для каждого стр из ДанныеПоРегистру.Ресурсы цикл
		ДоступныеПоля.Вставить(стр.имя,неопределено);
	конеццикла;	
	
	Данные=Новый Структура();
	для каждого стр из ДоступныеПоля цикл
		 ключ=стр.Ключ;
		 значение=ЭтотОбъект.Запись[Стр.Ключ];
		 Данные.Вставить(ключ,Строка(значение));
	 конеццикла;		
	 возврат Данные;
КонецФункции

При сохранении данных из формы регистра:

НаСервере
Функция СохранитьИзмененияЕслиТаковыеЕсть(ДанныеФормыДоИзменения)
	для каждого стр из ДанныеФормыДоИзменения цикл
		если стр.Значение<>Строка(ЭтотОбъект.Запись[Стр.Ключ]) тогда
			СК_ГР_РаботаСТранспортнымиФайлами.СделатьЗаписьОбИзменении(
				ЭтотОбъект.Запись["dt"],
				перечисления.СК_ГР_РегистрДляОбработки.Приборы,
				Строка(Стр.Ключ),
				Строка(стр.Значение),
				Строка(ЭтотОбъект.Запись[Стр.Ключ])
			);
		конецесли;	
	конеццикла;
КонецФункции	

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ДанныеФормыДоИзменения=ПолучитьДанныеДоОбновления();
КонецПроцедуры

В сам регистр «изменений», пишем так:

// Запись в регистр данных об изменении какого то поля в регистрах
// Вход:
//		Период - Дата загрузки из регистра
//		Изменяемый регистр - перечисления.СК_ГР_РегистрДляОбработки
//		Поле - изменяемое поле (строка)
//		Было - значение которое было (строка)
//		Стало - значение которое стало (строка)
Функция СделатьЗаписьОбИзменении(Период,Регистр,Поле,Было,Стало) экспорт
		
	МенеджерЗаписи = РегистрыСведений.СК_ГР_ИсторияИзменений.СоздатьМенеджерЗаписи(); 
		МенеджерЗаписи.Период=ТекущаяДата();
		МенеджерЗаписи.ПериодЗагрузки = Период; 
		МенеджерЗаписи.ИзменяемыйРегистр = Регистр; 
		МенеджерЗаписи.ИзменяемоеПоле = Поле; 
		МенеджерЗаписи.Было = Было; 
		МенеджерЗаписи.Стало = Стало; 
		МенеджерЗаписи.Исполнитель = Пользователи.ТекущийПользователь(); 
	МенеджерЗаписи.Записать();    			
КонецФункции	

1С: Получение текущего пользователя

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

Способ № 1

ПользователиИнформационнойБазы.ТекущийПользователь()

Способ №2

ОбщийМодульСистема.ОпределитьТекущегоПользователя();

Способ №3

ПользователиКлиентСервер.ТекущийПользователь()

Способ №4

Клиент - ПользователиКлиент.ТекущийПользователь()
Сервер - Пользователи.ТекущийПользователь()

Способ №5

ЗначениеТекущегоПользователя = ПараметрыСеанса.ТекущийПользователь;

Наиболее актуальный на текущий момент способ №4.

Подключение к фоновым заданиям 1С

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

ФоновыеЗадания.ПолучитьФоновыеЗадания();		

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

&НаКлиенте
Процедура ВыгрузкаКвитанцийНаБумаге(Команда)
	этаформа.ИндикаторВыгрузкаКвитанций=0;
	ЗапуститьФЗВыгрузкиКвитанций();					
	ПодключитьОбработчикОжидания("ИндикаторВыполненияВыгрузкиКвитанцийИсточник1",1,ложь);
	ПодключитьОбработчикОжидания("ИндикаторВыполненияВыгрузкиКвитанцийИсточник2",1,ложь);
КонецПроцедуры       

&НаСервере
Процедура ЗапуститьФЗВыгрузкиКвитанций()		
	Фоновые = ФоновыеЗадания.ПолучитьФоновыеЗадания();		
	Для Каждого Фоновое из Фоновые Цикл
		если Фоновое.ИмяМетода="СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник1" тогда
			если Фоновое.Состояние<>СостояниеФоновогоЗадания.ЗавершеноАварийно и Фоновое.Состояние<>СостояниеФоновогоЗадания.Завершено тогда
				сообщить("-предыдущее задание еще не завершено!");
				объект.ФЗ_ВыгрузкаКвитанций = Фоновое.УникальныйИдентификатор;									
				возврат;
			конецесли;
		конецесли;				
		если Фоновое.ИмяМетода="СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник2" тогда
			сообщить("-предыдущее задание еще не завершено!");
			если Фоновое.Состояние<>СостояниеФоновогоЗадания.ЗавершеноАварийно и Фоновое.Состояние<>СостояниеФоновогоЗадания.Завершено тогда
				сообщить("-предыдущее задание еще не завершено!");
				объект.ФЗ_ВыгрузкаКвитанций2 = Фоновое.УникальныйИдентификатор;									
				возврат;
			конецесли;
			возврат;
		 конецесли;							
	конеццикла;	
	
	Парм=Новый Структура("Период,ПроверятьНаличиевБД",объект.Период,объект.ПроверятьНаличиевБД);
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить(Парм);
	ФЗ = ФоновыеЗадания.Выполнить("СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник1",МассивПараметров);	
	объект.ФЗ_ВыгрузкаКвитанций = ФЗ.УникальныйИдентификатор;						
	ФЗ2 = ФоновыеЗадания.Выполнить("СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник2",МассивПараметров);	
	объект.ФЗ_ВыгрузкаКвитанций2 = ФЗ2.УникальныйИдентификатор;							
КонецПроцедуры

Т.е. если фоновое уже запущено — то просто получаем его идентификатор и отображаем прогресс бар. Если нет — запускаем

1 3 4 5 6 7 38