Оптимизация кода 1с, дополнительное обучение 1с.

1. Новичок1с 4 07.07.21 08:06 Сейчас в теме
Доброго дня.

Я ищу наставника, который готов помощь по моим вопросам 1с.

Мне нужно
1. Хотелось бы узнать, как можно оптимизировать код (именно с пояснениями, а не просто переписать код).
2. Посоветовать хорошую программу для обучения.
3. Я вижу свои пробелы в знании 1с и хотелось бы получить консультации только по интересующим вопросам.


Конечно же это за оплату.
Может быть есть у кого-то есть опыт программирования в 1с и желание быть наставником, то прошу Вас написать мне в личное сообщение для дальнейшего обсуждения.
По теме из базы знаний
Найденные решения
2. nomad_irk 76 07.07.21 08:13 Сейчас в теме
(1)При оптимизации кода важно понимать, что в итоге/какую именно оптимизацию вы хотите получить и за счет чего, а то может оказаться так, что и оптимизировать нечего.

Основные принципы оптимизации - сокращать количество вызовов функций/процедур/получения значений из БД, избавление от запросов в цикле.
Новичок1с; +1 Ответить
18. spacecraft 07.07.21 09:25 Сейчас в теме
(13)
2. Я бы сделала так
на клиенте
вызвала бы функцию реквизит номенклатуры
а на сервере делала бы запрос.

Самое главное не делать это в цикле для каждой строки ТЧ.
Далее, определить объем данных на форме. Если форма не "тяжелая" (не много реквизитов и табличных частей и в ТЧ не много колонок), то можно просто сделать контекстный серверный вызов, в котором запросом получить нужные данные и заполнить нужную колонку ТЧ.
Вот если форма тяжелая и контекстный вызов делается долго и требует оптимизации, только тогда ищется другой способ. Не раньше. Не стоит все оптимизировать заранее усложняя код.
Как вариант, можно выбрать ссылки номенклатур и его передать на сервер без контекста. Но тогда придется получать нужные данные по цене и заполнять на клиенте.
kot26rus; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. nomad_irk 76 07.07.21 08:13 Сейчас в теме
(1)При оптимизации кода важно понимать, что в итоге/какую именно оптимизацию вы хотите получить и за счет чего, а то может оказаться так, что и оптимизировать нечего.

Основные принципы оптимизации - сокращать количество вызовов функций/процедур/получения значений из БД, избавление от запросов в цикле.
Новичок1с; +1 Ответить
3. platonov.e 159 07.07.21 08:19 Сейчас в теме
)))
На сайте: 11 лет 11 месяцев


PS Спросить на форуме - бесплатно, для всего остального есть мастеркард)
o.nikolaev; mrx2012; +2 Ответить
4. Новичок1с 4 07.07.21 08:32 Сейчас в теме
(3)
Да, я давно на этот форуме и по многим вопросам он мне сильно помог.
Я читаю различные материалы, ищу решения возникающих проблем.

Только бывает так, что не получается или получается не совсем оптимально.
Я не отказываюсь оплатить услуги и я ищу такого человека, который готов лично со мной позаниматься 1с 8.3.
5. nomad_irk 76 07.07.21 08:35 Сейчас в теме
(4)в качестве обучения возьмите какой-то кусок кода, который по вашему мнению не является оптимальным, разместите его на форуме, можно даже в этой теме, коллективный разум вам даст некие советы по оптимизации конкретно этого кода.

Далее ваша задача интерполировать полученные знания на остальные случаи.
Новичок1с; +1 Ответить
6. platonov.e 159 07.07.21 08:43 Сейчас в теме
Что не так в этом куске кода?)

&НаКлиенте
Процедура Один()

Товары = Документ.Товары;

Для Каждого Стр ИЗ Товары Цикл

Цена = РеквизитНоменклатуры(Стр.Номенклатура, "Цена");

КонецЦикла;

КонецПроцедуры

&НаСервере
Процедура РеквизитНоменклатуры(Номенклатура, ИмяРеквизита)

Возврат Номенклатура[ИмяРеквизита];

Конецпроцдуры
Показать
7. nomad_irk 76 07.07.21 08:47 Сейчас в теме
(6) Как минимум:
1. Цена хранится в справочнике, в виде реквизита.
2. цикличное получения значения реквизита = запрос в цикле

:)
8. spacecraft 07.07.21 08:55 Сейчас в теме
(6) дополню )
1. Циклический контекстный вызов сервера. Данные желательно получать по возможности одним вызовом. И если возможно, то не контекстным.
2. Переменная Цена переназначается и нигде больше не используется )
9. platonov.e 159 07.07.21 09:00 Сейчас в теме
(7)
(8)
Ну да ну да, вы ж тут хотели научится оптимизировать...
11. nomad_irk 76 07.07.21 09:04 Сейчас в теме
(9)так это надо от ТС увидеть код и обоснование его неоптимальности.

Дать некий "сферический код в вакууме" и попросить объяснить в чем его неоптимальность - такое себе, человек может еще и не знает, на что обращать внимание при поиске неоптимальных участков кода.
10. platonov.e 159 07.07.21 09:01 Сейчас в теме
(8)
2. Переменная Цена переназначается и нигде больше не используется )

Я как будто c++ код компилил сейчас...
lefthander; +1 Ответить
12. lefthander 07.07.21 09:04 Сейчас в теме
(6)С практической точки зрения код бесполезен, он ничего не делает полезного. ;) И вот не понятно - Документ.Товары - точно на клиенте? ;)

(6)
Конецпроцдуры
ошибочки типа описочки
14. nomad_irk 76 07.07.21 09:07 Сейчас в теме
(12)
И вот не понятно - Документ.Товары - точно на клиенте? ;)


Вполне себе, только для чего - не понятно абсолютно, т.к. Документ.Товары(при условии, что Документ - это основной реквизит формы объекта) доступен на клиенте напрямую и нет особой необходимости присваивать это какой-либо переменной.
13. Новичок1с 4 07.07.21 09:05 Сейчас в теме
(6)


Возврат Номенклатура[ИмяРеквизита];
Я никогда не делала возврат из процедуры, только из функции, даже и не знаю, можно ли так делать.


2. Я бы сделала так
на клиенте
вызвала бы функцию реквизит номенклатуры
а на сервере делала бы запрос.


Показать
15. spacecraft 07.07.21 09:08 Сейчас в теме
(13)
Я никогда не делала возврат из процедуры, только из функции, даже и не знаю, можно ли так делать.

Конечно же нельзя. Но эта ошибка выскочит при сохранении конфигурации. Обращение к процедуре как к функции.
17. platonov.e 159 07.07.21 09:22 Сейчас в теме
(11) Но почему же? Когда человек ищет ошибку, он думает, происходит мыслительные процессы. Когда ему просто аргументировать, он это просто примет как факт. Когда он подумает, и ему потом аргументируют - то будет и то и то. Так что не вижу в таком методе что то плохое)

(12) Мы говорим об абстрактном куске кода, придуманным за 10 секунд) Его практическое значение - показать пример куска кода)

(13) Да, процедура не возвращает значения) Но это была лишь крохотная ошибка)
18. spacecraft 07.07.21 09:25 Сейчас в теме
(13)
2. Я бы сделала так
на клиенте
вызвала бы функцию реквизит номенклатуры
а на сервере делала бы запрос.

Самое главное не делать это в цикле для каждой строки ТЧ.
Далее, определить объем данных на форме. Если форма не "тяжелая" (не много реквизитов и табличных частей и в ТЧ не много колонок), то можно просто сделать контекстный серверный вызов, в котором запросом получить нужные данные и заполнить нужную колонку ТЧ.
Вот если форма тяжелая и контекстный вызов делается долго и требует оптимизации, только тогда ищется другой способ. Не раньше. Не стоит все оптимизировать заранее усложняя код.
Как вариант, можно выбрать ссылки номенклатур и его передать на сервер без контекста. Но тогда придется получать нужные данные по цене и заполнять на клиенте.
kot26rus; +1 Ответить
19. Новичок1с 4 07.07.21 09:36 Сейчас в теме
(18)

Выборка = Запрос.Выполнить().Выбрать();
		
	Пока 	Выборка.СледующийПоЗначениюПоля("ЛС")  Цикл
	
		//Если начало периода не пустая дата
		Если Выборка.НачалоПериода <>Дата(1,1,1)  Тогда 
			
			
			Док					= Документы.КУ_Претензия.СоздатьДокумент();
			ДОК.Дата			= ТекущаяДата();
			Док.Собственник 	= Выборка.ОтветственныйСобственник;
			
			//Чтобы период был равен периоду задолженности, а не весь период
			Док.НачалоПериода	= Мин(Выборка.НачалоПериода) ;
			Док.КонецПериода	= Макс(Выборка.КонецПериода );
			//		
			Док.Организация		= Организация;
			ДОк.Ответственный	= Справочники.Пользователи.НайтиПоНаименованию(имяПользователя());
			ДОк.Состояние		= СостояниеДОК;
			
			Если Выборка.ДатаЗакрытия<>Дата(1, 1, 1)  Тогда
				Док.Комментарий	= Строка("Закрытые лицевые счета!!!! от  "+Выборка.ДатаЗакрытия);  
			КонецЕсли;//Выборка.ДатаЗакрытия<> ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)  Тогда
			
			
			Пока Выборка.Следующий() Цикл
				Если Выборка.ПериодВзаиморасчетов <=Выборка.КонецПериода Тогда
					строкаТч					= Док.Задолженность.Добавить();
					СтрокаТЧ.ЛицевойСчет		= Выборка.ЛС;
					строкаТч.помещение			= Выборка.Помещение;
					СтрокаТЧ.ВидУслуги 			= Выборка.ВидУслуги;
					СтрокаТЧ.ПериодВзаиморасчетов=Выборка.ПериодВзаиморасчетов;
					СтрокаТЧ.СуммаВсего			= Выборка.СуммаВсего;
					СтрокаТЧ.СуммаДолга			= Выборка.СуммаДолга;
					СтрокаТЧ.СуммаПени			= Выборка.СуммаПени;
					//Док.Записать();
					
				КонецЕсли; // Выборка.ПериодВзаиморасчетов >=Выборка.НачалоПериода Тогда
				
			КонецЦикла; //Выборка.Следующий() Цикл
			
			Док.Записать();
			
		КонецЕсли;  //Выборка.НачалоПериода <>Дата(1,1,1,)  Тогда 
		
				
	КонецЦикла; //Пока 	Выборка.Следующий()  Цикл
	
Показать


spacecraft, вот кусок моего рабочего кода.
Я вначале делаю запрос, проверяю, есть ли нужные данные и далее по выбранным данным создаю новые документы, далее заполняя табличную часть.

Это всё в цикле.

Подскажите пожалуйста, это верное и оптимальное решение или у Вас есть предложения, как улучшить??

Дополню ещё.

Если ещё и другой документ, который создаётся на основании первого документа.
С такими же полями и с такой же самое табличной частью.
И как можно в 1 запросе и цикле, в зависимости от условий создать и заполнить 2 документа.

Как можно сделать этот цикл
21. Sashares 34 07.07.21 09:50 Сейчас в теме
(19)
1. Вы в каждой строке проверяете, что Начало периода не пустая дата, это условие можно перенести в запрос, чтобы он возвращал только нужные данные.
2. Вы ищите пользователя в цикле, его можно искать перед циклом, 1 раз, а потом просто присваивать.
3. Я бы в запрос добавил итоги по ЛС, чтобы делать обход результата запроса с группировкой, имхо, это более читаемо.
Новичок1с; +1 Ответить
24. Новичок1с 4 07.07.21 10:03 Сейчас в теме
(21)Sashares,

Имя пользователя я обычно выношу перед запросом, также как и переменные, которые для всех строчек одинаковые.

Пустая дата- понятно, поправлю.

А вот по итогам по ЛС и обход по результатам группировок- не совсем понятно для чего это нужно.
27. Sashares 34 07.07.21 10:12 Сейчас в теме
(24)
А вот по итогам по ЛС и обход по результатам группировок- не совсем понятно для чего это нужно.


Изменить текст запроса - добавить секцию ИТОГИ, изменить обработку результата запроса.

Например:

	//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
	// Данный фрагмент построен конструктором.
	// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ЛицевыеСчета.Ссылка КАК ЛицевойСчет,
		|	ЛицевыеСчетаДополнительныеРеквизиты.НомерСтроки КАК НомерСтроки,
		|	ЛицевыеСчетаДополнительныеРеквизиты.Свойство КАК Свойство,
		|	ЛицевыеСчетаДополнительныеРеквизиты.Значение КАК Значение,
		|	ЛицевыеСчетаДополнительныеРеквизиты.ТекстоваяСтрока КАК ТекстоваяСтрока
		|ИЗ
		|	Справочник.ЛицевыеСчета КАК ЛицевыеСчета
		|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ЛицевыеСчета.ДополнительныеРеквизиты КАК ЛицевыеСчетаДополнительныеРеквизиты
		|		ПО (ЛицевыеСчетаДополнительныеРеквизиты.Ссылка = ЛицевыеСчета.Ссылка)
		|ИТОГИ ПО
		|	ЛицевойСчет";
	
	РезультатЗапроса = Запрос.Выполнить();
	
	ВыборкаСсылка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	
	Пока ВыборкаСсылка.Следующий() Цикл
	    // тут в каждой строке выборки будет свой лицевой счет, остальные поля выборки в большинстве случаев будут не заполнены
		// количество строк в выборке = количеству лицевых счетов
		ВыборкаДетальныеЗаписи = ВыборкаСсылка.Выбрать();
	
		Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
			//тут будут детальные строки по текущему лицевому счету, который в ВыборкаСсылка.Лицевой счет
		КонецЦикла;
	КонецЦикла;
	
	//}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
Показать
28. Новичок1с 4 07.07.21 10:17 Сейчас в теме
(27)

Пока 	Выборка.СледующийПоЗначениюПоля("ЛС")  Цикл
Пока Выборка.Следующий() Цикл


Чем по оптимальности отличается Ваш код от моего??
29. Sashares 34 07.07.21 10:19 Сейчас в теме
(28) Дело не в оптимальности, дело в читаемости.
Например, если записать весь код в 1 строку, он будет работать быстрее.
Но это же не означает, что стоит так делать.
30. Новичок1с 4 07.07.21 10:26 Сейчас в теме
(29)

Попробую реализовать предложенный Вами способ.
32. Sashares 34 07.07.21 10:36 Сейчас в теме
(30)При использовании итогов в запросе, в запрос можно добавить Минимум и Максимум для полей НачалоПериода и ОкончаниеПериода - и в них будет как раз минимальное и максимальное значение полей по каждому лицевому счету.

ИТОГИ
	МАКСИМУМ(КонецПериода),
	МИНИМУМ(НачалоПериода)
ПО
	ЛицевойСчет


И в выборке по лицевым счетам эти поля будут заполнены.
33. Новичок1с 4 07.07.21 10:43 Сейчас в теме
(32)


Вот кстати тоже момент, где я пока что не нашла хорошего решения, я по этому поводу спрашивала как-то на форуме..

начало периода- это такое поле, которое получается из условий.
1. если не было док. претензия, то тогда с начала задолженности.
2 если есть док. претензия, то тогда начало периода = последний документ Претензия.КонецПериода + 1 день.


Если Объект.Задолженность.Количество()<>0 Тогда
		Для каждого Стр Из Объект.Задолженность Цикл
			//Чтобы период был равен периоду задолженности, а не весь период
			Запрос.УстановитьПараметр("НачалоПериода",	Стр.НачалоПериода);
			//Ставим конец периода текущую дату потому, что ЛС мог оплатить
			Запрос.УстановитьПараметр("КонецПериода",	КонецДня(ТекущаяДата()));
		КонецЦикла; //Для каждого Стр Из ТаблицаДолг Цикл
	КонецЕсли; //Объект.Задолженность.Количество()<>0 Тогда




Пользователи вручную создают и заполняют документы претензия и исковое заявление.
Я сделала этот код ради интереса, но им всё равно никто не пользуется.
34. nomad_irk 76 07.07.21 10:46 Сейчас в теме
(33)Если можно делать запросом, делайте именно им.
22. spacecraft 07.07.21 09:55 Сейчас в теме
(19) тут цикл правомерен, так как по другому и не получится. Мы не говорили, что сам факт наличия цикла это плохо.

//Чтобы период был равен периоду задолженности, а не весь период
Док.НачалоПериода = Мин(Выборка.НачалоПериода) ;
Док.КонецПериода = Макс(Выборка.КонецПериода );

Вот этот код совсем не понятно, зачем в нем функции Мин и Макс? Они ничего не делают.

Далее, заполнение табличной части можно упростить, если в запросе получать представления имен полей такое же как в ТЧ.
Тогда можно использовать так:
            Пока Выборка.Следующий() Цикл
                Если Выборка.ПериодВзаиморасчетов <=Выборка.КонецПериода Тогда
                    строкаТч                    = Док.Задолженность.Добавить();
                    ЗаполнитьЗначенияСвойств(СтрокаТЧ, Выборка);
                КонецЕсли; // Выборка.ПериодВзаиморасчетов >=Выборка.НачалоПериода Тогда
                
            КонецЦикла; //Выборка.Следующий() Цикл


Это то сразу бросилось в глаза.
Новичок1с; +1 Ответить
25. Новичок1с 4 07.07.21 10:09 Сейчас в теме
(22)
Вот этот код совсем не понятно, зачем в нем функции Мин и Макс? Они ничего не делают.

Далее, заполнение табличной части можно упростить, если в запросе получать представления имен полей такое же как в ТЧ.
Тогда можно использовать так:
Пока Выборка.Следующий() Цикл
Если Выборка.ПериодВзаиморасчетов =Выборка.НачалоПериода Тогда

КонецЦикла; //Выборка.Следующий() Цикл



Благодарю Вас за пояснение, поняла.
23. nomad_irk 76 07.07.21 09:55 Сейчас в теме
(19) 1.
Справочники.Пользователи.НайтиПоНаименованию(имяПользователя())

вынесити за цикл, потому что получается запрос в цикле

2.
Если Выборка.ПериодВзаиморасчетов <=Выборка.КонецПериода Тогда
                    строкаТч                    = Док.Задолженность.Добавить();
                    СтрокаТЧ.ЛицевойСчет        = Выборка.ЛС;
                    строкаТч.помещение            = Выборка.Помещение;
                    СтрокаТЧ.ВидУслуги             = Выборка.ВидУслуги;
                    СтрокаТЧ.ПериодВзаиморасчетов=Выборка.ПериодВзаиморасчетов;
                    СтрокаТЧ.СуммаВсего            = Выборка.СуммаВсего;
                    СтрокаТЧ.СуммаДолга            = Выборка.СуммаДолга;
                    СтрокаТЧ.СуммаПени            = Выборка.СуммаПени;
                    //Док.Записать();
 КонецЕсли;
Показать


замените на

Если Выборка.ПериодВзаиморасчетов <=Выборка.КонецПериода Тогда
                    ЗаполнитьЗначенияСвойств(Док.Задолженность.Добавить(), Выборка);
 КонецЕсли;
Новичок1с; +1 Ответить
26. Новичок1с 4 07.07.21 10:09 Сейчас в теме
(23)

Спасибо за замечания
31. nomad_irk 76 07.07.21 10:36 Сейчас в теме
(26)ну и еще я бы посмотрел на запрос, т.к. им нужно максимально готовые данные выгребать из БД.
50. Новичок1с 4 07.07.21 19:41 Сейчас в теме
(18)
А как быть в таком случае.
Есть к примеру в выборке из запроса 100 различных строк, где есть сумма. Необходимо для каждой суммы сделать сумму прописью (обращение к функции числоПрописью)
Делаю так:
Пока выборка.следующий () цикл 
      суммаПрописью =  числоПрописью(выборка.сумма);
КонецЦикла;


Т.е получается, что каждый раз в цикле идёт обращение к функции.
51. spacecraft 07.07.21 20:00 Сейчас в теме
(50) именно в таком виде код бессмыслен. суммаПрописью тупо перезаписывается )
Но если о самой технике получения числа прописью в цикле для каждой строки выборки, то это нормально. По другому не сделать.
Тут не идет получение данных из базы данных в цикле и не вызов сервера с клиента в цикле. Именно об этом и речь. Сам по себе цикл это нормально. Просто нужно понимать, когда его не желательно использовать.
FatPanzer; +1 Ответить
53. Новичок1с 4 07.07.21 20:13 Сейчас в теме
(51)
Далее это суммаПрописью попадает в печатную форму.

Понятно, благодарю Вас за ответ.
52. FatPanzer 07.07.21 20:11 Сейчас в теме
(50) Поддержу (51) и добавлю:
1. Плохо - выполнение запросов цикле (обращение к БД, нагрузка SQL). Или обращение к функциям и процедурам, которые используют обращение к БД.
2. Нормально - работа с циклами в оперативной памяти - один раз запросом получили данные из БД, они загрузились в оперативную память (выборка находится в ОЗУ), и тут их уже можно и нужно вертеть циклами (но с умом!).

И да, ваш код не имеет смысла.
Новичок1с; +1 Ответить
54. Новичок1с 4 07.07.21 20:18 Сейчас в теме
(52)
Пока выборка.следующий () цикл 
      суммаПрописью =  числоПрописью(выборка.сумма);

//добавлю тут также
ОбластьПечати.Параметры.СуммаПрописью = суммаПрописью;

КонецЦикла;

Показать


Так имеет смысл?
55. FatPanzer 07.07.21 20:23 Сейчас в теме
(54) Да (но при условии либо смены области, либо её вывода в результат:
ОбластьПечати = Макет.ПолучитьОбласть(ИмяОбласти);
Пока Выборка.Следующий () Цикл
    ОбластьПечати.Параметры.СуммаПрописью = ЧислоПрописью(Выборка.Сумма);
    ТабДок.Вывести(ОбластьПечати);
КонецЦикла;

PS. Попытайтесь писать операторы с Большой Буквы. УНасТакПринято. ЭтоУважениеККоллегам.
58. Новичок1с 4 07.07.21 20:32 Сейчас в теме
(55)
Я стараюсь так и писать, сейчас просто с телефона пишу, поэтому не удобно всегда делать большие буквы.

У меня такой же рабочий код, как и в Вашем примере.
56. spacecraft 07.07.21 20:24 Сейчас в теме
(54) нет смысла создавать промежуточную переменную, если можно без нее и она больше не используется далее.
Заполнение параметров так же надежнее заполнять заполнением свойств. В запросе или макете даете сопоставимые имена и все параметры сразу заполняете по выборке. Так не будет ошибки времени выполнения. Максимум это данные не подставятся, но ошибка не выскочит.
Новичок1с; +1 Ответить
57. FatPanzer 07.07.21 20:30 Сейчас в теме
(56) Согласен, но в данном примере это вычисляемое поле (не СКД). Поэтому либо через прямое присвоение параметру значения функции, либо не через Выборку, а через ТЗ с добавлением колонки...
59. spacecraft 07.07.21 20:32 Сейчас в теме
(57) да, я не обратил внимание на получение числа прописью.
Но и даже в таком случае лучше создать Структуру с нужными ключами по параметрам печатной формы и заполнить через нее.
FatPanzer; +1 Ответить
61. Новичок1с 4 07.07.21 20:47 Сейчас в теме
(57)
Если можно, поясните пожалуйста, как в ТЗ добавить колонку СуммаПрописью??
Как для всей Выборки из Запроса выполнить функцию ЧислоПрописью??
62. FatPanzer 07.07.21 20:53 Сейчас в теме
(61) 1. ТЗ.Колонки.Добавить("СуммаПрописью", Новый ОписаниеТипов("Строка"));
2. Никак. Здесь только перебор строк ТЗ или Выборки. Потому что в качестве параметра функции выступает конкретное число, которое вы сможете взять только из конкретной строки. Читаем СП.
64. Новичок1с 4 07.07.21 21:09 Сейчас в теме
(62)
Ясно, до этого значит я не так поняла Вас и не верно задала прошлый вопрос.
Пункт 1 я иногда так и делаю.
71. Новичок1с 4 21.07.21 15:58 Сейчас в теме
(62)
Подскажите пожалуйста, а как добавить колонки в ТЗ на форме (не является реквизитом обработки, данные заполняются из результатов запросов).
Пробую так

ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));

в таком случае ругается.

Я в запрос добавила пустую колонку.

 |0 КАК МоёЧисло,

В цикле по строкам ТЗ я редактирую эту колонку, таким образом работает.
72. FatPanzer 21.07.21 16:38 Сейчас в теме
(71) Новый РеквизитФормы() - это если программно.
А в конструкторе - на самом реквизите есть пункт добавления подчиненных колонок к табличному реквизиту (не к элементу!)
60. Новичок1с 4 07.07.21 20:37 Сейчас в теме
(56)
Вы мне сегодня про заполнение ТЧ документа также подсказали.
В печатной форме я это уже раньше реализовала, а вот про заполнение ТЧ документа не знала.

Просто привела пример кода, где идёт получение ЧислоПрописью

P.s.

Спасибо Вам огромное за пояснения. Реально, перечитывая сообщения или когда необходима помощь, то именно такие подробные сообщения и помогают понять.
63. spacecraft 07.07.21 21:07 Сейчас в теме
(60) вот так можно было бы сделать, если данные из выборки нужно обрабатывать дополнительно. Параметров области может быть несколько. Указываем их при создании структуры.
Пока выборка.следующий () цикл 
    ПараметрыОбласти = Новый Структура("Парам1,Парам2,СуммаПрописью");
    ЗаполнитьЗначенияСвойств(ПараметрыОбласти, Выборка);
    ПараметрыОбласти["СуммаПрописью"] =  числоПрописью(выборка.сумма);

    ОбластьПечати.Параметры.Заполнить(ПараметрыОбласти);
    ТабДок.Вывести(ОбластьПечати);

КонецЦикла;
Показать

Если постобработка данных из выборки не нужна, то можно обойтись без структуры и заполняем параметры сразу из выборки.
65. Новичок1с 4 07.07.21 21:31 Сейчас в теме
Такой вариант кода, когда из Структуры заполняем Табличной Документ, то для меня эта новая информация.

Необходимо попробовать, как это будет работать.
16. Xershi 1490 07.07.21 09:18 Сейчас в теме
К оптимизации нужно подходить с практической стороны.
Если код работает за приемлемое время и вы лучше его не напишите, то оптимизировать нечего.
А так обращайтесь, проконсультирую.
starik-2005; +1 Ответить
20. ImHunter 315 07.07.21 09:45 Сейчас в теме
(1) Почитайте книги по совершенному коду и рефакторингу. Тот же, Совершенный код (Макконнелл). Понятно, что там не про 1С. Но многое по полочкам разложится.
Новичок1с; +1 Ответить
35. starik-2005 3043 07.07.21 13:57 Сейчас в теме
Забей. Оптимальный код - это гемор. Да и не нужен они никому толком.

Пример: можно загрузить список недействительных паспортов в базу 1С за 10 часов. Можно просто записать недействительные паспорта в 5000 файлов за 40 минут. Можно хитро загрузить их в 1С за 10 минут, но не в таблицу. От первого решения до третьего в части оптимизации прошло четыре года. Стоило? Может быть...

Забей.
38. Sashares 34 07.07.21 14:42 Сейчас в теме
(35)А обновлять потом эти 5000 файлов как?
45. starik-2005 3043 07.07.21 18:29 Сейчас в теме
(38) просто затираешь за те же 40 минут. По ним нет разностной копии - они валятся вперемешку.

Зы: в файловых потоках есть возможность дописать в конец файла. Очень быстро и просто.
39. Sashares 34 07.07.21 14:42 Сейчас в теме
(35)
Можно хитро загрузить их в 1С за 10 минут, но не в таблицу.

А куда?
40. FatPanzer 07.07.21 15:07 Сейчас в теме
(39) Нуу.... В ХранилищеНастроек, например )))))
42. starik-2005 3043 07.07.21 15:45 Сейчас в теме
(39) а сколько у Вас денег?
43. Sashares 34 07.07.21 16:52 Сейчас в теме
(42)А у вас?
Если вы не хотите раскрывать особенности реализации, можно так и сказать, ваше дело.
Платить вам чисто из любопытства я не собираюсь.

Но тогда зачем тогда писать об этих ваших достижениях в каждой теме, не очень понятно. Неужели ради ЧСВ?
44. starik-2005 3043 07.07.21 18:27 Сейчас в теме
(43) нет ручек - нет конфеток. Могу доступ к сервису дать для тестирования скорости
FatPanzer; +1 Ответить
46. Sashares 34 07.07.21 18:38 Сейчас в теме
(44)У меня нет задачи загрузки недействительных паспортов.
Поэтому и в доступе к сервису смысла нет.
Это был интерес о загрузке большого количества данных в базу, т.к. это довольно распространенная задача.
Если вы ничего по теме рассказать не можете, ок. Нет, так нет.
47. starik-2005 3043 07.07.21 18:43 Сейчас в теме
(46) в жанном случае грузить это в базу долго, дорого и раьотает потом медленно.

А по поводу загрузки в базу, то если архитектура хотя бы третьей нормальной форме соответствует, то со скоростью можно работать.

1С грузит так долго потому, что у нее проблемы с апдейтами - она сначала удаляет, потом вставляет, а вставка - это новые данные, удаленные данные скульный сервак бережно хранит. Поэтому без типа нарушения типа лицензионного соглашения нельзя что-то быстро загрузить в 1С.

Все задачи решаются очень большим количествлм методов, и большинство методов - правильные.
48. spacecraft 07.07.21 19:14 Сейчас в теме
(47)
в жанном случае

Опечатка по Фрейду? В каком месте букву на д менять? )))
66. starik-2005 3043 07.07.21 21:43 Сейчас в теме
(48) в одном))

А Фрейд в Жанном случае ни при чем.
49. FatPanzer 07.07.21 19:15 Сейчас в теме
67. nomad_irk 76 07.07.21 22:43 Сейчас в теме
(49) truncate - это только 50% действия :)
36. succub1_5 89 07.07.21 14:20 Сейчас в теме
Недавно оптимизировал такой код:
Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    РеализацияТоваровУслуг.Ссылка 
        |ИЗ
        |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
        |        ГДЕ
|  РеализацияТоваровУслуг.Проведен
| РеализацияТоваровУслуг.Дата МЕЖДУ ДатаС И ДатаПо";
   Запрос.УстановитьПараметр("ДатаС", ТекущаяДата()-3*86400);
Запрос.УстановитьПараметр("ДатаПо", ТекущаяДата()); 
    Результат = Запрос.Выполнить();
    
    Выборка = Результат.Выбрать();
    
ТЗ_ИНН = Новый ТаблицаЗначений;
ТЗ_ИНН.Колонки.Добавить("ИНН");

    Пока Выборка.Следующий() Цикл
        НовСтр = ТЗ.Добавить();
НовСтр.ИНН = Выборка.Ссылка.Организация.ИНН;
    КонецЦикла;
ТЗ_ИНН.Свернуть("ИНН");
Показать


А еще жалобы были - что иногда ошибка вываливается на строке с Выборка = Результат.Выбрать();
37. nomad_irk 76 07.07.21 14:32 Сейчас в теме
(36)это ж классика говнокода :)

А еще жалобы были - что иногда ошибка вываливается на строке с Выборка = Результат.Выбрать();


И какая там ошибка появлялась?
41. FatPanzer 07.07.21 15:09 Сейчас в теме
(36) Вообще-то еще на этапе Запрос.Выполнить() должно упасть. В секции ГДЕ отсутствует соединитель условия "И".
68. Новичок1с 4 21.07.21 08:15 Сейчас в теме
Доброго утра.

Я хочу продолжить эту тему
у меня возник такой вопрос.
Я соединяю ТЗ с новым запросом.


ТЗ = Объект.ТЗ.Выгрузить();
....................................................

|ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.КУ_Взаиморасчеты.ОстаткиИОбороты(, &КонецПериода, , , ) КАК КУ_ВзаиморасчетыОстатки
....................................................
|ГДЕ
	|	
	| КУ_ВзаиморасчетыОстатки.ПериодВзаиморасчетов >= НАЧАЛОПЕРИОДА(ТаблицаДолг.НачалоПериода, ДЕНЬ)


....................................................


Показать


Как указать НачалоПериода в этом условии так
ТЗ.НачалоПериода т.е. данные из строки ТЗ?


На данном этапе указано так
//Если Объект.ТЗ.Количество()<>0 Тогда
	//	Для каждого Стр Из Объект.ТЗЦикл
		//	Запрос.УстановитьПараметр("НачалоПериода",	Стр.НачалоПериода);
		//КонецЦикла; //Для каждого Стр Из ТЗЦикл
	//КонецЕсли; //Объект.ТЗ.Количество()<>0 Тогда
	//
69. spacecraft 21.07.21 09:04 Сейчас в теме
(68) все зависит от того, какие данные нужны для выборки.
Обычно для такого случая проще соединять с таблицей движения, чем использовать виртуальную таблицу (ОстаткиИОбороты).
Если нужны обороты, то можно так:
Запрос = Новый Запрос;
Запрос.Текст = "
		|ВЫБРАТЬ
		|	ТЗ.НачалоПериода КАК НачалоПериода,
		|	ТЗ.Контрагент КАК Контрагент
		|ПОМЕСТИТЬ ВТ_ТЗ
		|ИЗ
		|	&ТЗ КАК ТЗ
		|;
		|
		|////////////////////////////////////////////////////////////­////////////////////
		|ВЫБРАТЬ
		|	ВТ_ТЗ.Контрагент КАК Контрагент,
		|	СУММА(ВЫБОР
		|			КОГДА Взаиморасчеты.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
		|				ТОГДА Взаиморасчеты.Сумма
		|			ИНАЧЕ -Взаиморасчеты.Сумма
		|		КОНЕЦ) КАК Сумма
		|ИЗ
		|	ВТ_ТЗ КАК ВТ_ТЗ
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.КУ_Взаиморасчеты КАК Взаиморасчеты
		|		ПО (Взаиморасчеты.Контрагент = ВТ_ТЗ.Контрагент)
		|			И (Взаиморасчеты.Период >= ВТ_ТЗ.НачалоПериода)
		|			И (Взаиморасчеты.Период < &КонецПериода)
		|
		|СГРУППИРОВАТЬ ПО
		|	Взаиморасчеты.Контрагент
		|";
		
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.УстановитьПараметр("ТЗ", Объект.ТЗ.Выгрузить());
Показать


Соответственно еще указать соединение по другим полям...
Новичок1с; +1 Ответить
70. Новичок1с 4 21.07.21 09:12 Сейчас в теме
(69)spacecraft , благодарю Вас за предложенное решение.

То, как Вы делаете- я делала немного по иному, например так я не делала.
Отличные Вы приводите примеры, подробные и с описанием.

Запрос.УстановитьПараметр("ТЗ", Объект.ТЗ.Выгрузить());
73. Новичок1с 4 22.07.21 20:38 Сейчас в теме
Доброго вечера.
Подскажите пожалуйста, оптимален ли такой код.
1. Из ТЧ на форме я выгрузила некоторые колонки в ТЗСуммыПрописью , затем изменила из значения и добавила новые колонки.
2. При печати идёт обращение в цикле к этой функции.

Функция ОбластьНиз(ИмяМакета,КодЛС) 				//Суммы прописью 
	ПарПредмета		= "рубль,рубля,рублей,м,копейка,копейки,копеек,ж,2";
	ФормСтрока 		= "Л = ru_RU; ДП = Истина";
	
	//19.07.2020
	Обработка	= РеквизитФормыВЗначение("Объект");
	Макет 		= Обработка.ПолучитьМакет(ИмяМакета); 
	ОбластьНиз 		= Макет.ПолучитьОбласть("Низ");
	
	Если  ТЗ.Количество()<> 0 Тогда 
		
		ТЗСуммыПрописью = СуммыПрописью ();
		Для Каждого Строка ИЗ ТЗСуммыПрописью Цикл
			Если Строка.КодЛС = КодЛС Тогда				
	        	ОбластьНиз.Параметры.Заполнить(Строка);
			КонецЕсли; // Строка.КодЛС = КодЛС Тогда	
		КонецЦикла; //Для Каждого Строка ИЗ ТЗ Цикл

	  КонецЕсли; //  ТЗ.Количество()<> 0 Тогда 
	
	  	
	Возврат ОбластьНиз;	
КонецФункции //СуммыПрописью(ИмяМакета,СуммаДолгаПр,СуммаПениПр,ГоспошлинаПР,СуммаВсегоПр) //Суммы прописью

//Вызов функции 
Процедура Печать()
Пока Выборка.Следующий() Цикл
   ОбластьСуммаДолгаПрописью = 
   ОбластьСуммаДолга(ИмяМакета, Выборка.КодЛС);

КонецЦикла;
КонецПроцедуры
Показать
74. Новичок1с 4 22.07.21 22:26 Сейчас в теме
(73)

Вспомнила про такое решение
Если  ТЗ.Количество()<> 0 Тогда 
		ТЗСуммыПрописью = СуммыПрописью ();
			
		//Идём по строкам ТЗСуммыПрописью 
		Для Каждого СтрокаТЗ Из ТЗСуммыПрописью Цикл
			СтрокаТЗ.КодЛС = КодЛС;
			//Делаю отбор в ТЗ и иду только по текущему ЛС
			//https://helpme1c.ru/tablica-znachenij-v-yazyke-1s-8-v-primerax
			ОтборСумм = Новый Структура;
			ОтборСумм.Вставить("КодЛС", КодЛС);
			СтрокиСумм = ТЗСуммыПрописью.НайтиСтроки(ОтборСумм);
			Для Каждого Строка Из СтрокиСумм Цикл
				ОбластьНиз.Параметры.Заполнить(Строка);
			КонецЦикла; //Для Каждого Строка ИЗ ТЗ Цикл
		КонецЦикла; //Для Каждого Строка ИЗ ТЗ Цикл
	КонецЕсли; //  ТЗ.Количество()<> 0 Тогда 
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот