Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Как получить список реквизитов КОП (число прочтений - 2596 )
recop
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 247
Местоположение: Калуга
Зарегистрирован: 06. Июня 2017
Пол: Мужской
Как получить список реквизитов КОП
05. Апреля 2018 :: 07:20
Печать  
Как программно получить список реквизитов КОП?

Появилась необходимость дублировать объект созданный КОП. Реквизиты имеют значения типа таблиц, списков и аналогичных объектов. Класс в процессе разработки.
  
Наверх
 
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #1 - 05. Апреля 2018 :: 07:25
Печать  
  
Наверх
www  
IP записан
 
recop
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 247
Местоположение: Калуга
Зарегистрирован: 06. Июня 2017
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #2 - 05. Апреля 2018 :: 07:31
Печать  
Оперативно! Спасибо.
  
Наверх
 
IP записан
 
recop
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 247
Местоположение: Калуга
Зарегистрирован: 06. Июня 2017
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #3 - 05. Апреля 2018 :: 07:47
Печать  
Блин. Совсем спекся. Как получить значение по имени?
  
Наверх
 
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #4 - 05. Апреля 2018 :: 08:17
Печать  
recop писал(а) 05. Апреля 2018 :: 07:47:
Блин. Совсем спекся. Как получить значение по имени?

Сервис.ПолучитьПеременнуюКонтекста(<Контекст>,<ИмяПеременной>,<Результат>)
  
Наверх
www  
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #5 - 05. Апреля 2018 :: 08:21
Печать  
ещё вариант
Код
Выбрать все
Функция ПеременнаяКонтекста(Конт, ИмяПеременной) Экспорт
	ТекстМодуля = "
	|Функция ЗначениеПеременной(Источник)
	|	Возврат Источник."+ИмяПеременной+";
	|КонецФункции
	|";

	Модуль = Фаб.Модуль(Конт, ТекстМодуля);

	Возврат Модуль.ЗначениеПеременной(Конт);
КонецФункции


Функция УстановитьПеременную(Конт, ИмяПеременной, Значение) Экспорт
	ТекстМодуля = "
	|Функция УстЗнач(з)
	|	"+ИмяПеременной+" = з;
	|	Возврат "+ИмяПеременной+";
	|КонецФункции
	|";

	Модуль = Фаб.Модуль(Конт, ТекстМодуля);

	Возврат Модуль.УстЗнач(Значение);
КонецФункции
 


в качестве рыбы для копирования всякого
Код
Выбрать все
Процедура КопироватьРеквизиты_Значение(Приемник, Имя, Зн, фТолькоНеПустые, фТолькоПустыеПриемника)
	Если фТолькоНеПустые = 1 Тогда
		Если ПустоеЗначение(Зн) = 1 Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;

	Если фТолькоПустыеПриемника = 1 Тогда
		ЗнП = ПеременнаяКонтекста(Приемник, Имя);
		Если ПустоеЗначение(ЗнП) = 0 Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;

	Если ТипЗначенияСтр(Приемник) = "СписокЗначений" Тогда
		Приемник.Установить(Имя, Зн);
	Иначе
		Попытка
			УстановитьПеременную(Приемник, Имя, Зн);
		Исключение
			Если глФлагОтладки = 1 Тогда
				Сообщить("Копир.рекв.: ошибочка: в "+Приемник+" нет "+Имя);
			КонецЕсли;
		КонецПопытки;
	КонецЕсли;
КонецПроцедуры

Процедура КопироватьРеквизиты(Приемник, Источник, стрРекв, фТолькоНеПустые = 0, фТолькоПустыеПриемника = 0) Экспорт
	Если ТипЗначенияСтр(стрРекв) = "СписокЗначений" Тогда
		сзРекв = стрРекв;
	ИначеЕсли стрРекв = "*" Тогда
		сзРекв = СоздатьОбъект("СписокЗначений");
		ТипИст = ТипЗначенияСтр(Источник);
		Если ТипИст = "СписокЗначений" Тогда
			Для н = 1 По Источник.РазмерСписка() Цикл
				Имя = "";
				Источник.ПолучитьЗначение(н, Имя);
				сзРекв.ДобавитьЗначение(Имя);
			КонецЦикла;
		ИначеЕсли ТипИст = "ТаблицаЗначений" Тогда
			Для н = 1 По Источник.КоличествоКолонок() Цикл
				Имя = "";
				Имя = Источник.ПолучитьПараметрыКолонки(н);
				сзРекв.ДобавитьЗначение(Имя);
			КонецЦикла;
		ИначеЕсли ТипИст = "Структура" Тогда
			Для н = 1 По Источник.Количество() Цикл
				Имя = "";
				Источник.Получить(н, Имя);
				сзРекв.ДобавитьЗначение(Имя);
			КонецЦикла;

		КонецЕсли;
	Иначе
		сзРекв = СтрокуВСписок(стрРекв, ",", 1);
	КонецЕсли;

	Если ТипЗначенияСтр(Источник) = "СписокЗначений" Тогда
		Для нИст = 1 По Источник.РазмерСписка() Цикл
			Имя = "";
			Зн = Источник.ПолучитьЗначение(нИст, Имя);
			Если стрРекв <> "" Тогда
				Если сзРекв.НайтиЗначение(Имя) = 0 Тогда
					Продолжить;
				КонецЕсли;
			КонецЕсли;
			КопироватьРеквизиты_Значение(Приемник, Имя, Зн, фТолькоНеПустые, фТолькоПустыеПриемника);
		КонецЦикла;

	Иначе
		Для н = 1 По сзРекв.РазмерСписка() Цикл
			Имя = сзРекв.ПолучитьЗначение(н);
			Зн = ПеременнаяКонтекста(Источник, Имя);
			КопироватьРеквизиты_Значение(Приемник, Имя, Зн, фТолькоНеПустые, фТолькоПустыеПриемника);
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры
 

  
Наверх
 
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #6 - 05. Апреля 2018 :: 08:23
Печать  
Фаб::Модуль()
Код
Выбрать все
Функция Модуль(Конт, ТекстМодуля) Экспорт
	Модуль = СоздатьОбъект("ВыполняемыйМодуль");
	Модуль.УстановитьМодуль(ТекстМодуля);
	Модуль.НазначитьКонтекст(Конт);
	Модуль.КомпилироватьМодуль();
	Модуль.ВыполнитьМодуль();
	Возврат Модуль;
КонецФункции
 



собственно, Фаб - это у меня фабрика, которая клепает всякие ходовые объекты по упрощённой схеме.
  
Наверх
 
IP записан
 
recop
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 247
Местоположение: Калуга
Зарегистрирован: 06. Июня 2017
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #7 - 05. Апреля 2018 :: 13:37
Печать  
Супер! Осталось решить как обработать перекрестную ссылку.
Спасибо!

Как по скорости на больших массивах?
  
Наверх
 
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #8 - 06. Апреля 2018 :: 05:00
Печать  
За большие массивы ничего не скажу, видимо не пробовал Улыбка
Все эти штуки слеплены с другой целью: сократить количество тупого кода, повысить читабельность. Накладных расходов при таком копировании  наверное раз в четыре - пять больше, по сравнению с  ТЗ.а = ТЗ.б;
  
Наверх
 
IP записан
 
recop
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 247
Местоположение: Калуга
Зарегистрирован: 06. Июня 2017
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #9 - 06. Апреля 2018 :: 07:28
Печать  
ADirks писал(а) 05. Апреля 2018 :: 08:23:
Фаб::Модуль()
Код
Выбрать все
Функция Модуль(Конт, ТекстМодуля) Экспорт
	Модуль = СоздатьОбъект("ВыполняемыйМодуль");
	Модуль.УстановитьМодуль(ТекстМодуля);
	Модуль.НазначитьКонтекст(Конт);
	Модуль.КомпилироватьМодуль();
	Модуль.ВыполнитьМодуль();
	Возврат Модуль;
КонецФункции
 




Что-то не получается получить значение переменной:
Модуль = ВыполняемыйМодуль

Где ловить возвращаемое значение?
  
Наверх
 
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #10 - 06. Апреля 2018 :: 08:31
Печать  
как-то так
Код
Выбрать все
Функция Фаб_Модуль(Конт, ТекстМодуля) Экспорт
	Модуль = СоздатьОбъект("ВыполняемыйМодуль");
	Модуль.УстановитьМодуль(ТекстМодуля);
	Модуль.НазначитьКонтекст(Конт);
	Модуль.КомпилироватьМодуль();
	Модуль.ВыполнитьМодуль();
	Возврат Модуль;
КонецФункции

Функция ПеременнаяКонтекста(Конт, ИмяПеременной) Экспорт
	ТекстМодуля = "
	|Функция ЗначениеПеременной(Источник)
	|	Возврат Источник."+ИмяПеременной+";
	|КонецФункции
	|";

	Модуль = Фаб_Модуль(Конт, ТекстМодуля);

	Возврат Модуль.ЗначениеПеременной(Конт);
КонецФункции

Функция УстановитьПеременную(Конт, ИмяПеременной, Значение) Экспорт
	ТекстМодуля = "
	|Функция УстЗнач(з)
	|	"+ИмяПеременной+" = з;
	|	Возврат "+ИмяПеременной+";
	|КонецФункции
	|";

	Модуль = Фаб_Модуль(Конт, ТекстМодуля);

	Возврат Модуль.УстЗнач(Значение);
КонецФункции


//===========================================================
ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Кол1");
ТЗ.НоваяСтрока();


УстановитьПеременную(ТЗ, "Кол1", "=====");
Кол1 = ПеременнаяКонтекста(ТЗ, "Кол1");
 

  
Наверх
 
IP записан
 
recop
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 247
Местоположение: Калуга
Зарегистрирован: 06. Июня 2017
Пол: Мужской
Re: Как получить список реквизитов КОП
Ответ #11 - 08. Апреля 2018 :: 06:52
Печать  
СПАСИБО ВСЕМ!

Общими усилиями копирование класса:

Код
Выбрать все
function ПолучитьЗначение(varName) export
	var Модуль,ТекстМодуля;

	ТекстМодуля = "
	|function ЗначениеПеременной(Источник)
	|	return Источник."+varName+";
	|endfunction
	|";

	Модуль = СоздатьОбъект("ВыполняемыйМодуль");
	Модуль.УстановитьМодуль(ТекстМодуля);
	Модуль.НазначитьКонтекст(глВзятьКонтекст(Контекст));
	Модуль.КомпилироватьМодуль();
	Модуль.ВыполнитьМодуль();

	return Модуль.ЗначениеПеременной(глВзятьКонтекст(Контекст));

endfunction // ПолучитьЗначение()

function УстановитьЗначение(varName,Значение) export
	var Модуль,ТекстМодуля;

	ТекстМодуля = "
	|function УстановитьЗначение(з)
	|	"+varName+" = з;
	|	return "+varName+";
	|endfunction
	|";

	Модуль = СоздатьОбъект("ВыполняемыйМодуль");
	Модуль.УстановитьМодуль(ТекстМодуля);
	Модуль.НазначитьКонтекст(Контекст);
	Модуль.КомпилироватьМодуль();
	Модуль.ВыполнитьМодуль();

	return Модуль.УстановитьЗначение(Значение);

endfunction // УстановитьЗначение()

function ОбработкаЗначения(Значение)
	var result,name,i,ii;
	var Тип,Длина,Точность;

	if ТипЗначенияСтр(Значение)="СписокЗначений" then
		result=СоздатьОбъект("СписокЗначений");
		for i=1 to Значение.РазмерСписка() do
			result.ДобавитьЗначение(ОбработкаЗначения(Значение.ПолучитьЗначений(i)));
		enddo;
	elsif ТипЗначенияСтр(Значение)="ТаблицаЗначений" then
		result=СоздатьОбъект("ТаблицаЗначений");
		for i=1 to Значение.КоличествоКолонок() do
			name = Значение.ПолучитьПараметрыКолонки(i,Тип,Длина,Точность);
			result.НоваяКолонка(name,Тип,Длина,Точность);
		enddo;
		for i=1 to Значение.КоличествоСтрок() do
			result.НоваяСтрока();
			for ii=1 to Значение.КоличествоКолонок() do
				result.УстановитьЗначение( i, ii, ОбработкаЗначения( Значение.ПолучитьЗначение(i,ii) ) );
			enddo;
		enddo;
	elsif ТипЗначенияСтр(Значение)=ТипЗначенияСтр(глВзятьКонтекст(Контекст)) then
		result=СоздатьОбъект(ТипЗначенияСтр(глВзятьКонтекст(Контекст)));
	else
		result=Значение;
	endif;

	return result;

endfunction // ОбработкаЗначения()


function Выгрузить(КОП) export
	var type,inform,TzP;

	type=ТипЗначенияСтр(глВзятьКонтекст(Контекст));
	if ТипЗначенияСтр(КОП)<>type then
		КОП=СоздатьОбъект(type);
	endif;

	inform = СоздатьОбъект("Информатор");
	TzP=inform.ПолучитьТаблицуСвойств(КОП);
	TzP.ВыбратьСтроки();
	while TzP.ПолучитьСтроку()=1 do
		КОП.УстановитьЗначение( TzP.NameRus, ОбработкаЗначения( ПолучитьЗначение(TzP.NameRus) ) );
	enddo;

endfunction // Выгрузить()

 



К сожалению Сервис Альфа опять подвёл:

    Сервис.ПолучитьПеременнуюКонтекста(глВзятьКонтекст(Контекст),TzP.NameRus,value) = 0 Печаль

, было бы покороче...
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать