• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

7.7 Изменение Элемента Справочника

  • Автор темы olga13
  • Дата начала
O

olga13

Добрый день. Суть проблемы такова: при проведении приходного документа в справочник "ПартииТовара" записывается элемент, являющийся реквизитом табличной части. Если документ проводится впервые, все ОК. А если его перепровести, партия исчезает.
Вот кусок глобального модуля:

Код:
	Спр = СоздатьОбъект("Справочник.ПартииТовара");
Спр.ИспользоватьВладельца(Конт.Товар);

Ключ = СокрЛП(ТекДок) + "&" + СокрЛП(СтрПартии);
Если Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 0 Тогда
Спр.Новый();
КонецЕсли;

Спр.Ключ 		= Ключ;
Спр.ПоДок 		= ТекДок.ТекущийДокумент();
Спр.Фирма 		= Фирма;
Спр.СтрПартии 	= СтрПартии;
Спр.ДатаПрихода	= ДатаПрихода;
Спр.Контрагент 	= Контрагент;
Спр.Договор 	= Договор;
Спр.ТТН 		= ТТН;
Спр.Страна		= Страна;
Спр.ПерваяЦена	= ПерваяЦена;
Спр.УчетнаяЦена	= УчетнаяЦена;

Спр.Записать();

Конт.Партия = Спр.ТекущийЭлемент();

Все работает нормально до строки Спр.Записать(). После этого значение Спр становиться пустым. Не пойму, почему? Ведь с новым элементом все работает нормально.
 
Д

Дайнеко

На первый взгляд выглядит корректно. Выскажу замечания:

* Как всегда раздражает излишний текст. "Страна" и "ТТН" и прочее на ситуацию влияют?
"Спр.Ключ = Ключ;" было бы достаточно.

* Чуть важнее. О фразе "Вот кусок глобального модуля". Глядя на текст есть некоторое недоумение: а откуда этот фрагмент вызван, какой у него контекст? Объясню подробнее:
- Спр.ИспользоватьВладельца(Конт.Товар) - догадываюсь, что проце передан "Контекст" как параметр "Конт".
- Спр.ПоДок = ТекДок.ТекущийДокумент(); - а кто такой "ТекДок"? Почему не "Конт"?
- Спр.Фирма = Фирма; - и все последующие комаеды. А тут я вообще в расстеряности. Наверняка "Фирма" это реквизит документа. Как тогда к нему обращается проца? Без всяких "Конт" и ТекДок.

* Теперь о главном. Вместо
Спр.ИспользоватьВладельца(Конт.Товар);
надо
Спр.Владелец = Конт.Товар;

* И о самом главном. Если мой совет действенен, то в качестве условия его использования прошу строку
Если Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 0 Тогда
заменить на
Если НЕ(Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 1) Тогда

* Совсем не главное. Сама идея автоматически создавать партии не видится толковой. Без комм.
 
E

evgenyatam

* Теперь о главном. Вместо
Спр.ИспользоватьВладельца(Конт.Товар);
надо
Спр.Владелец = Конт.Товар;

Надо и то и то. Первое влияет на поиск. хотя если ключ уникальный не зависимо от номенклатуры - то ИспользоватьВладельца не надо.

Добавлено: * И о самом главном. Если мой совет действенен, то в качестве условия его использования прошу строку
Если Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 0 Тогда
заменить на
Если НЕ(Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 1) Тогда

Не влияет. тоесть эти 2 строки эквивалентны.
 
O

olga13

* Как всегда раздражает излишний текст. "Страна" и "ТТН" и прочее на ситуацию влияют?
"Спр.Ключ = Ключ;" было бы достаточно.
Почему же излишний? Я же написала, что это кусок модуля, а не процедура. Я не стала вставлять все, поскольку это к делу не относится. Там, как раз-таки, в зависимости от вида документа присваиваются значения переменным.

Спр.ИспользоватьВладельца(Конт.Товар) - догадываюсь, что проце передан "Контекст" как параметр "Конт".
Правильно догадываетесь.

Спр.ПоДок = ТекДок.ТекущийДокумент(); - а кто такой "ТекДок"? Почему не "Конт"?
Не "Конт", потому что документом партии может быть другой документ, а не тот, который вызвал процедуру.

Спр.Фирма = Фирма; - и все последующие комаеды. А тут я вообще в расстеряности. Наверняка "Фирма" это реквизит документа. Как тогда к нему обращается проца? Без всяких "Конт" и ТекДок.
См. п. 1.

И о самом главном. Если мой совет действенен, то в качестве условия его использования прошу строку
Если Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 0 Тогда
заменить на
Если НЕ(Спр.НайтиПоРеквизиту("Ключ", Ключ, 0) = 1) Тогда
Насколько я помню, мы на эту тему уже дискутировали. Я знаю, что вас мой синтаксис раздражает. Но по-моему, это дело привычки. Я наоборот, не люблю эти перевертыши, мне удобнее видеть "=0" или "=1". А на результат проверки условия это абсолютно не влияет.

Совсем не главное. Сама идея автоматически создавать партии не видится толковой. Без комм.
Опять-таки дело привычки. Мне кажется, что удобнее видеть целиком весь документ, а не открывать каждую партию, чтобы проверить правильность заполнения реквизитов.

Теперь о главном. Вместо
Спр.ИспользоватьВладельца(Конт.Товар);
надо
Спр.Владелец = Конт.Товар;
Попробовала, ругается:
Спр.Владелец = Конт.Товар;
{Глобальный модуль(385)}: Не выбран элемент!

В принципе, я уже нашла выход. Добавила переменную "Партия", теперь все работает:

Партия = Спр.ТекущийЭлемент();

Спр.Записать();

Конт.Партия = Партия;

Но мне хочется понять, почему в первоначальном варианте не работало? Я ведь спозиционировалась на элементе справочника, почему при сохранении существующего элемента он теряется?
 
E

evgenyatam

Но мне хочется понять, почему в первоначальном варианте не работало? Я ведь спозиционировалась на элементе справочника, почему при сохранении существующего элемента он теряется?

Да потому что после НайтиПоРеквизиту в спр содержится не ссылка. а правильнее было бы:

Спр.Записать();

Конт.Партия = Спр.ТекущийЭлемент();
 
O

olga13

Но мне хочется понять, почему в первоначальном варианте не работало? Я ведь спозиционировалась на элементе справочника, почему при сохранении существующего элемента он теряется?

Да потому что после НайтиПоРеквизиту в спр содержится не ссылка. а правильнее было бы:

Спр.Записать();

Конт.Партия = Спр.ТекущийЭлемент();

Дык у меня ж так и было. Как раз-таки этот вариант и не работает. После Спр.Записать() значение Спр.ТекущийЭлемент() становится пустым.
 
Д

Дайнеко

В принципе, я уже нашла выход. Добавила печременную "Партия", теперь все работает:
Партия = Спр.ТекущийЭлемент();
Спр.Записать();
Конт.Партия = Партия;

Простите за резкость: чушь полная. Если Спр это объект Нового элемента, еще не записанного, то метод Спр.ТекущийЭлемент() вернет пустоту. Он возвращает объект из Базы данных. evgenyatam указал правильный вариант.

Попробовала, ругается:
Спр.Владелец = Конт.Товар;

Да у Вас, похоже, нелады с Конт.Товар.
Если Вы настойчивый человек, ищите первопричину и разбирайтесь с пониманием инструментов а не делайте шаманские пассы по принципу: "авось обману".
 
O

olga13

Если Вы настойчивый человек, ищите первопричину и разбирайтесь с пониманием инструментов а не делайте шаманские пассы по принципу: "авось обману".

Я и пытаюсь найти причину, иначе бы не писала на форум. Вопрос, где искать.
Честно говоря, я вообще не понимаю, какое отношение это имеет Конт.Товар и Спр.Владелец к моей проблеме. Тут как раз-таки все работает. Меня волнует, куда пропадает Спр.ТекущийЭлемент() после Спр.Записать(). Если смотреть в отладчике, значение становится пустым.
Я думаю, каким-то образом повлияло то, что я установила основное представление элемента справочника "ПартииТовара" в виде кода. До этого все работало прекрасно.
 
P

Paume

Честно говоря, я вообще не понимаю, какое отношение это имеет Конт.Товар и Спр.Владелец к моей проблеме.
Ну, тут можно еще предположить, что выборка открывается в пределах подчинения, а когда записывается - владелец может оказаться другим, вот ТекущийЭлемент() и пропадает. Для того, чтобы насильно переписать владельца, стоит не просто написать Спр.Владелец = Конт.Товар; Я когда-то наталкивалась на такие то ли грабли, то ли непонимание мною самого процесса, но у меня тоже ругалось и я обходила вот так:
СпрНом = СоздатьОбъект("Справочник.Товары");
СпрНом.НайтиЭлемент(Конт.Товар);
И только после этого
Спр.Владелец = СпрНом.ТекущийЭлемент();

По-моему, стоит попробовать в отладчике проследить за владельцем.

А вот это
Партия = Спр.ТекущийЭлемент();
с новым элементом точно работает?
 
O

olga13

А вот это
Цитата:




Партия = Спр.ТекущийЭлемент();





с новым элементом точно работает?

Нет, конечно, с новым элементом не работает. Поэтому приходится извращаться и по-разному обрабатывать старый и новый элемент.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!