Имя: Пароль:
1C
 
АктСверки
0 Denian
 
14.11.24
10:06
Добрый день. Тут бухи попросили в документе Акт сверки в табличной части по данным нашей организации в поле представление добавить после запятой счет фактуру это именно для корректировки реализации и сторно, я написал код, но они жалуются что он отрабатывает в районе 30-40 минут , а так как  я новичок в этом деле, то не совсем понимаю что не так с кодом. Вот сам код:
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
	
	Если ПараметрыЗаписи.РежимЗаписи = ПредопределенноеЗначение("РежимЗаписиДокумента.Проведение") Тогда
		ОценкаПроизводительностиКлиент.НачатьЗамерВремени(Истина, "ПроведениеАктСверкиВзаиморасчетов");
	КонецЕсли;
	
	// Получаем табличную часть "ПоДаннымОрганизации" документа
	Строки = ЭтаФорма.Объект.ПоДаннымОрганизации;

	// Проходим по строкам табличной части
	Для Каждого Строка Из Строки Цикл

		// Получаем значение реквизита "Представление"
		ЗначениеПредставления = Строка.Представление;

		// Проверяем, является ли значение строкой и не является ли пустым
		Если ТипЗнч(ЗначениеПредставления) = Тип("Строка") И НЕ ПустаяСтрока(ЗначениеПредставления) Тогда
			
			// Если это корректировка продажи
			Если Лев(ЗначениеПредставления, 21) = "Корректировка продажи" Тогда
				// Получаем номер корректировочной счет-фактуры
				НомерСчетФактуры = ПолучитьНомерКорректировочнойСчетФактуры(Строка.Документ);
				
				// Если нашли номер счет-фактуры, добавляем его к представлению, если его там еще нет
				Если НомерСчетФактуры <> "" И Не НайденоВСтроке(Строка.Представление, НомерСчетФактуры) Тогда
					Строка.Представление = Строка.Представление + ", Счет-фактура: " + НомерСчетФактуры;
				КонецЕсли;
			КонецЕсли;

			// Если это сторнируемый документ
			Если Лев(ЗначениеПредставления, 6) = "Сторно" Тогда
				// Поиск номера счет-фактуры обычного документа
				НомерСчетФактурыСторно = ПолучитьНомерСчетФактурыПоСторно(Строка.Документ); 

				// Если счет-фактура найдена и её номер еще не добавлен в представление
				Если НомерСчетФактурыСторно <> "" И Не НайденоВСтроке(Строка.Представление, НомерСчетФактурыСторно) Тогда
					Если ПустаяСтрока(Строка.Представление) Тогда
						Строка.Представление = "Счет-фактура: " + НомерСчетФактурыСторно;
					Иначе
						Строка.Представление = Строка.Представление + ", Счет-фактура: " + НомерСчетФактурыСторно;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;

		КонецЕсли;
	КонецЦикла;

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


// Функция для поиска номера корректировочной счет-фактуры
&НаСервере
Функция ПолучитьНомерКорректировочнойСчетФактуры(ДокументКорректировки)
	// Создаем новый запрос
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|   СчетФактураВыданный.Номер КАК НомерСФ
	|ИЗ
	|   Документ.СчетФактураВыданный КАК СчетФактураВыданный
	|ГДЕ
	|   СчетФактураВыданный.ДокументОснование = &Документ";

	// Устанавливаем параметр документа корректировки
	Запрос.УстановитьПараметр("Документ", ДокументКорректировки);
	
	// Выполняем запрос
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	// Если нашли номер счет-фактуры, возвращаем его
	Если Выборка.Следующий() Тогда
		Возврат Выборка.НомерСФ;
	Иначе
		// Если номер не найден возвращаем пустую строку
		Возврат "";
	КонецЕсли;
КонецФункции

// Функция для получения номера счет-фактуры по сторнируемому документу
&НаСервере
Функция ПолучитьНомерСчетФактурыПоСторно(ДокументСторно)
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|   СчетФактураВыданный.Номер КАК НомерСФ
	|ИЗ
	|   Документ.СчетФактураВыданный КАК СчетФактураВыданный
	|ГДЕ
	|   СчетФактураВыданный.ДокументОснование = &ДокументОснование";

	// Устанавливаем параметр "ДокументОснование" — это будет СторнируемыйДокумент
	Запрос.УстановитьПараметр("ДокументОснование", ДокументСторно.СторнируемыйДокумент);

	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();

	// Проверяем, найден ли номер счёт-фактуры
	Если Выборка.Следующий() Тогда
		Возврат Выборка.НомерСФ;
	Иначе
		Возврат "";
	КонецЕсли;
КонецФункции

// Функция для проверки наличия строки в другом значении
Функция НайденоВСтроке(Строка, Поиск)
	Возврат Найти(Строка, Поиск) > 0;
КонецФункции
1 osa1C
 
14.11.24
06:28
(0) Грубая ошибка всех новичков - запрос в цикле детектед! Тебе надо получить всё одним запросом, а у тебя выполняется +100500 запросов.
Начинай запрос с выбора строк табличной части и к ним левым соединением прикрепляй счет-фактуры.
2 osa1C
 
14.11.24
06:56
(0) что-то в таком духе надо делать. Писал "на коленке", но должно быть примерно так. И никаких вызовов твоих функций с запросами из цикла. Запрос в цикле - это самое плохое, что может быть!

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

30-40 мин даже этот код не может работать.


(2)

1) Допустим по РТУ есть два счёта: помеченный на удаление и проведенный.
-- кроме очевидно не нужного помеченного на удаление, вы размножили строки

2) вери хьюморес

АктСверкиВзаиморасчетовПоДаннымОрганизации.Ссылка = СчетФактураВыданный.ДокументОснование

Документ.АктСверкиВзаиморасчетов.ПоДаннымОрганизации КАК АктСверкиВзаиморасчетовПоДаннымОрганизации
ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактураВыданный
ПО АктСверкиВзаиморасчетовПоДаннымОрганизации.Ссылка = СчетФактураВыданный.ДокументОснование


3) Лень смотреть, но "вроде как" счф можно выписывать на основании нескольких РТУ
(табчасть "ДокументыОснования")
5 osa1C
 
14.11.24
07:58
(3) Тебе запросы надо изучать. Почитай книгу Хрусталевой "Язык запросов"
6 osa1C
 
14.11.24
08:02
(4) Я не писал готовый запрос. Я просто показал направление, спасибо за критику.
7 Мультук
 
14.11.24
08:24
(0)

Наконец-то я увидел

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)

У тебя (ИМХО) большую часть времени занимают серверные вызовы
Потому что ты не понимаешь разницы между &НаСервере и &НаСервереБезКонтекста

Напиши отдельную процедуру "НаСервере" и вызови её одни раз.

ИЛИ

&НаСервереБезКонтекста
Функция ПолучитьНомерКорректировочнойСчетФактуры(

&НаСервереБезКонтекста
Функция ПолучитьНомерСчетФактурыПоСторно(ДокументСторно)
8 Denian
 
14.11.24
10:04
(7)  До изменений по замерам показывало ~9 секунд, а после изменений ~5
9 denk32
 
14.11.24
12:03
(0) Если это БП то лучше представление заполнять в процедуре Документы.АктСверкиВзаиморасчетов.ПодготовитьДанныеДляЗаполнения, а не ПередЗаписью. Там как раз есть процедура ДополнитьТаблицуСчетамиФактурами.
10 Климов Сергей
 
14.11.24
12:05
(0) А почему вы заполнение табличной части при записи документа делаете? Там есть команда заполнения. Вот её и модифицируйте.
Желательно в расширении.
11 Denian
 
14.11.24
12:15
(10) Я ради интереса на копии привязал к записи, вообще изначально пытался с помощью команды заполнения, но не смог найти откуда берется представление , чтобы сразу там его непосредственно менять.
12 Климов Сергей
 
14.11.24
12:21
(11) Это чревато следующими событиями: пользователь жмёт кнопку "Заполнить", видит одно. Жмёт "Записать и закрыть", потом открывает - видит другое. У него истерика: враги тайно меняют нам акты сверки. Звонок вам, в пятницу вечером, часов в семь, с криками, слезами и требованием всех поймать и вернуть как было. Оно вам надо?
13 Denian
 
14.11.24
12:33
(12) Я им сразу сказал, мол по приколу добавил на кнопку записать нажмете появится счетфактура по новой заполните пропадёт, кивнули, а потом звонят мы ждем уже 40 минут пока отработает ваша штука ну я и убрал, а сейчас сижу мучаюсь
14 Волшебник
 
14.11.24
12:41
(11) (13) "ради интереса", "по приколу".... Вы вообще нормальный?
15 Denian
 
15.11.24
05:16
(14) Вполне да, не вижу в этом ничего такого, учитывая что это просто эксперименты тем более на копии
16 Ненавижу 1С
 
15.11.24
07:55
(4) там в цикле вызовы с клиента сервера. От наполненности табличной части зависит. На приличных объемах - может
17 Мультук
 
15.11.24
08:21
(16)

В (7) я ему об этом написал
В (8) он ответил, что "по замерам показывало ~9 секунд, а после изменений ~5"

Почему в (0) дело шло о 40 мин, а потом внезапно стали секунды - я не знаю. Догадываться лень.
18 Волшебник
 
15.11.24
08:40
(15) Ну так сколько секунд или минут выполняется Ваш программный код?
19 Denian
 
15.11.24
09:21
(18) Если брать Акт сверки в котором 833 документа, то около 5-6 секунд процесс идет, я закидывал этот код в оригинальную базу и там начали поступать звонки что компы зависают ожидание от получаса и выше. Почему так я не понимаю даже если математически считать пусть к ним 5к или 10к приходит документов в одном акте это всяко меньше 30 минут работы. А провести все акты скопом они же не могут ну так чтобы запрос отработал.
В свое оправдание скажу только то что я 3 месяц в 1С и меня сразу кинули в бурную работу писать доработки обновлять конфигурации и тд поэтому я "чайный чайник"
20 Волшебник
 
15.11.24
09:27
(19) Уберите свой программный код из ПередЗаписью. Заведите кнопку "Заполнить счета-фактуры"
21 Гена
 
15.11.24
09:52
(0) Чем, позвольте узнать, не устраивает данная опция?
22 Гена
 
15.11.24
10:16
Если не устраивает, что в Представление попадают ВСЕ СФ, а надо только корр и сторно, то согласитесь, что м.б. не стоит с нуля писать код, а просто обрезать типовой. Да вот хоть по оператору GoTo (Перейти) )
23 Волшебник
 
15.11.24
10:20
(22) о, Гена узнал про новую игрушку в платформе :)
24 Гена
 
15.11.24
10:27
(23) Да что-то вроде со школы осталось в памяти
IF ... GO TO 1250 [номер строки - не шучу, все строки там нумеровались )]
25 Denian
 
15.11.24
12:27
(21) Честно говоря эту опцию даже не искал, по крайней мере не было надежд на то что она есть , но сейчас это всё упрощает. Я изначально хотел привязать код к кнопке заполнить по нашей организации, но очень долго пытался разобраться и найти где и куда там можно запихнуть по итогу сделал как есть.  Все равно спасибо будут знать хоть что такая штучка есть (21) (22)
26 Eiffil123
 
15.11.24
12:33
(24) это в каких-то диалектах BASIC так было, что строки нумеровались
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший