|   |   | 
| 
 | АктСверки | ☑ | ||
|---|---|---|---|---|
| 0
    
        Denian naïve 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 naïve 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 naïve 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 naïve 14.11.24✎ 12:15 | 
        (10) Я ради интереса на копии привязал к записи, вообще изначально пытался с помощью команды заполнения, но не смог найти откуда берется представление , чтобы сразу там его непосредственно менять.     | |||
| 12
    
        Климов Сергей 14.11.24✎ 12:21 | 
        (11) Это чревато следующими событиями: пользователь жмёт кнопку "Заполнить", видит одно. Жмёт "Записать и закрыть", потом открывает - видит другое. У него истерика: враги тайно меняют нам акты сверки. Звонок вам, в пятницу вечером, часов в семь, с криками, слезами и требованием всех поймать и вернуть как было. Оно вам надо?     | |||
| 13
    
        Denian naïve 14.11.24✎ 12:33 | 
        (12) Я им сразу сказал, мол по приколу добавил на кнопку записать нажмете появится счетфактура по новой заполните пропадёт, кивнули, а потом звонят мы ждем уже 40 минут пока отработает ваша штука ну я и убрал, а сейчас сижу мучаюсь     | |||
| 14
    
        Волшебник 14.11.24✎ 12:41 | 
        (11)(13) "ради интереса", "по приколу".... Вы вообще нормальный?     | |||
| 15
    
        Denian naïve 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 naïve 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 naïve 15.11.24✎ 12:27 | 
        (21) Честно говоря эту опцию даже не искал, по крайней мере не было надежд на то что она есть , но сейчас это всё упрощает. Я изначально хотел привязать код к кнопке заполнить по нашей организации, но очень долго пытался разобраться и найти где и куда там можно запихнуть по итогу сделал как есть.  Все равно спасибо будут знать хоть что такая штучка есть (21) (22)     | |||
| 26
    
        Eiffil123 15.11.24✎ 12:33 | 
        (24) это в каких-то диалектах BASIC так было, что строки нумеровались     | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |