Реклама на этом месте
Форум 1С
Форум 1С
Программистам. Бухгалтерам. Администраторам. Пользователям
Задай вопрос - получи решение проблемы. Без троллинга и флуда.
16 Дек 2017, 12:11
МультиВход
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?
 
collapse

Автор Тема: Проверка наличия товара  (Прочитано 4631 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Юлия56

  • *
  • Сообщений: 7
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-11-04
  • Сайт: 
Есть регистр Накопления Движение, вид движения- остатки. Регистр имеет измерения (покупатель, товар), ресурс (сумма, количество, скидка), есть документы поставка и продажа товара. Необходимо  чтоб при продаже товара в  документе продажа осуществлялась проверка на наличие товара.
Вот код который написала, но он не срабатывает((( Помогите исправить ошибку!! Очень нужно сделать
Для Каждого Стр Из ТабличнаяЧасть1 Цикл
   Дата = ТекущаяДата();
    Товар = ТекСтрокаТабличнаяЧасть1.Товар;
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |   ДвижениеОстатки.товар.Наименование,
   |   ДвижениеОстатки.количествоОстаток
   |ИЗ
   |   РегистрНакопления.Движение.Остатки КАК ДвижениеОстатки";
   Запрос.УстановитьПараметр("Товар", Стр.Товар);
   Выборка = Запрос.Выполнить().Выбрать();
   Если Не ТекСтрокаТабличнаяЧасть1.Количество() = 0 Тогда
    Результат.Следующий();
      Если ТекСтрокаТабличнаяЧасть1.Количество() > ПоставляемыеТовары.количество Тогда
         Сообщить("Превышение остатка");
      КонецЕсли;
   КонецЕсли;
КонецЦикла;

Сейчас при проверки кода выводит сообщение о том что переменная Результат и ПоставляемыеТовары не определена


Оффлайн tepliym

  • *
  • Сообщений: 24
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-01-28
  • Сайт: 
  • Профессия: Программист 8.1
Для Каждого Стр Из ТабличнаяЧасть1 Цикл
   Дата = ТекущаяДата();
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   | ДвижениеОстатки.Номенклатура,
   | ДвижениеОстатки.КоличествоОстаток
   |ИЗ
   | РегистрНакопления.Движение.Остатки(&Дата, ) КАК ДвижениеОстатки
   |ГДЕ
   | ТоварыНаСкладахОстатки.Номенклатура = &Товар";
   Запрос.УстановитьПараметр("Товар", Стр.Товар);
     Запрос.УстановитьПараметр("Дата", Дата);
   Выборка = Запрос.Выполнить().Выбрать();
   Если Выборка.Следующий() Тогда
   Если Стр.Количество > Выборка.КоличествоОстаток Тогда
         Сообщить("Превышение остатка");
КонецЕсли;
 Иначе
Сообщить("Товара нет на складе " + Стр.Товар)
КонецЕсли;
   КонецЦикла;
Примерно так, должно работать.

Оффлайн Юлия56

  • *
  • Сообщений: 7
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-11-04
  • Сайт: 
Спасибо большое!!!! Получилось выводить системное сообщение превышение остатка) Толь я ене много изменила ваш код.
Для Каждого Стр Из ТабличнаяЧасть1 Цикл
   Дата = ТекущаяДата();
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ДвижениеОстатки.Товар,
   |    ДвижениеОстатки.КоличествоОстаток
   |ИЗ
   |    РегистрНакопления.Движение.Остатки(&Дата, ) КАК ДвижениеОстатки
   |ГДЕ
   |    ДвижениеОстатки.Товар = &Товар";
   Запрос.УстановитьПараметр("Товар", Стр.Товар);
     Запрос.УстановитьПараметр("Дата", Дата);
   Выборка = Запрос.Выполнить().Выбрать();
   Если Выборка.Следующий() Тогда
       Если Стр.Количество > Выборка.КоличествоОстаток Тогда
         Сообщить("Превышение остатка");
     КонецЕсли;
 Иначе
     Сообщить("Товара нет на складе " + Стр.Товар)
    КонецЕсли;
   КонецЦикла;


У меня еще один вопрос) Не смотря на то что выходит системное сообщение, я могу осуществить проведение и запись документа, а можно ее как-то запретить если система сообщила что остаток превышен??

Оффлайн tepliym

  • *
  • Сообщений: 24
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-01-28
  • Сайт: 
  • Профессия: Программист 8.1

У меня еще один вопрос) Не смотря на то что выходит системное сообщение, я могу осуществить проведение и запись документа, а можно ее как-то запретить если система сообщила что остаток превышен??

А процедуре обработки проведения документа поставе оператор Возврат по нужному условию.

Оффлайн Юлия56

  • *
  • Сообщений: 7
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-11-04
  • Сайт: 
Спасибо за подсказку! Я не особо владею познаниями в области 1С ((( я напишу в процедуре Возврат "" , а как сформулировать это условие?? оно будет называться "Отменить проведение" ??

Оффлайн tepliym

  • *
  • Сообщений: 24
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-01-28
  • Сайт: 
  • Профессия: Программист 8.1
Процедура ОбработкаПроведения(Отказ, РежимПроведения)

 Для Каждого Стр Из ТабличнаяЧасть1 Цикл
   Дата = ТекущаяДата();
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ДвижениеОстатки.Номенклатура,
   |    ДвижениеОстатки.КоличествоОстаток
   |ИЗ
   |    РегистрНакопления.Движение.Остатки(&Дата, ) КАК ДвижениеОстатки
   |ГДЕ
   |    ТоварыНаСкладахОстатки.Номенклатура = &Товар";
   Запрос.УстановитьПараметр("Товар", Стр.Товар);
     Запрос.УстановитьПараметр("Дата", Дата);
   Выборка = Запрос.Выполнить().Выбрать();
   Если Выборка.Следующий() Тогда
       Если Стр.Количество > Выборка.КоличествоОстаток Тогда
         Сообщить("Превышение остатка");
        Отказ = Истина;
     КонецЕсли;
 Иначе
     Сообщить("Товара нет на складе " + Стр.Товар);
    Отказ = Истина;
    КонецЕсли;
   КонецЦикла;

    Если Отказ Тогда
        Возврат;
    КонецЕсли;
ЭтотОбъект.Записать(РежимЗАписиДокумента.Проведение);

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

Оффлайн Юлия56

  • *
  • Сообщений: 7
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-11-04
  • Сайт: 
Спасибо большое!!!!
Только теперь когда осуществляется запись, а потом проведение нужных (верных)документов конфигурация зависает и программа не отвечает((

Оффлайн LexaK

  • *****
  • Сообщений: 1267
  • РЕПУТАЦИЯ: 347
  • КПД: 27%
  • Регистрация: 2012-05-16
  • Сайт: 
  • Профессия: Программист 1С
Юлия56, 1С очень чувствительна к коду, одну и ту-же обработку можно написать оптимально и неоптимально, при оптимальном варианте все выполнится за пару секунд, при неоптимальном 1С будет висеть, а на самом деле все процессоры в поте лица будут выполнять ваш тупой код!
тот код что вы написали далек от оптимальности, поэтому 1С и висит.

в вашем случае, при проведении документа надо создать 1 ОДИН запрос и ОДИН раз его выполнить,
а не ТЫСЯЧУ раз как вы это делаете в цикле, перебирая товарную часть, у вас 1000 (а может и 10 000 , сколько товаров в товарной части?) раз вызывается расчет получение остатков, 1000 раз формируется новый запрос отправляется на сервер, там выполняется и возращается результат, и все это в тысячекратном размере!!! (да, не повезло фирме)

в вашей задаче надо оперировать сразу со всей табличной частью в запросе
примерный код процедуры проверки наличия остатков

пример ниже написан в другой базе, для другого документа и регистра,
просто замените на свои документ и регистр. (в примере есть еще пара мест которые можно оптимизировать, но это уже для любителей писать очень оптимальный код)

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

Отказ = ПроверкаОстатков();
Если Отказ Тогда
//проверка не прошла, все сообщения сделаны в функции,
//просто выходим
Возврат;
КонецЕсли;

//здесь дальнейший код по проведению документа!

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

Функция ПроверкаОстатков()

лкЗапрос = новый Запрос;
лкЗапрос.Текст = "
|//подготавливаем таблицу с товарами по документу
|//заодно суммируем количество одинаковых товаров
|//так как в товарной части, в разных строчках,
|//могут быть одинаковые товары!!!
|ВЫБРАТЬ
| //Док.Ссылка,
| Док.Номенклатура,
| Сумма(Док.Количество) как Количество
|поместить Таб
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Док
|где
| Док.Ссылка = &Ссылка
|Сгруппировать по
| //Док.Ссылка,
| Док.Номенклатура
|;
|Выбрать
| Таб.*,
| Рег.КоличествоОстаток как Остаток
|из
| Таб
|левое соединение
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &Дата,
| //Склад = &Склад     //ВАЖНО! Если есть склад в документе, включите условие по складу
| //только для нужных товаров получаем остатки!!!
| Номенклатура в (выбрать Номенклатура из Таб) ) КАК Рег
| по Таб.Номенклатура = Рег.Номенклатура
|Где
| //при условии что в документе количество по товарам всегда > 0
| ЕстьNull(Рег.КоличествоОстаток,0) < Таб.Количество
|упорядочить по
| Таб.Номенклатура
|автоупорядочивание
|
|
|";

лкЗапрос.УстановитьПараметр("Дата",Дата);
лкЗапрос.УстановитьПараметр("Ссылка",Ссылка);
лкРезультат = лкЗапрос.Выполнить();

Если лкРезультат.Пустой() Тогда
//результат пустой,
//значит в документе нет Товара по которому нехватает остатка
Возврат Ложь;
КонецЕсли;

лкРезультат = лкРезультат.Выгрузить();
//выводим одну строку - заголовок, информция о проводимом документе
//всегда помним о пакетных обработках!!!
Сообщить("Нехватает остатков по документу: " + Ссылка);
//вместо сообщить можно использовать другие методы, лог в файл
Для каждого лкСтр Из лкРезультат Цикл
//здесь выводим только сообщения по нехватке количества
//указываем товар, сколько надо отгрузить, и какой остаток
Сообщить("Товар: " + лкСтр.Номенклатура
   + " требуется: " + лкСтр.Количество
   + " вналичии: " + лкСтр.Остаток );
КонецЦикла;

//Отказ будет Истина, документ не запишется и не проведется!
Возврат Истина;

КонецФункции //



Помогло? - Нажми СПАСИБО!!!
                       :)

Оффлайн cska-fanat-kz

  • 1С:Специалист
  • Глобальный модератор
  • *****
  • Сообщений: 5745
  • РЕПУТАЦИЯ: 1099
  • КПД: 19%
  • Красная армия всех сильней!
  • Регистрация: 2010-11-06
    • Skype: cska-fanat-kz81
  • Сайт: cska-fanat-kz.ucoz.kz
  • Профессия: Разработчик 1С
tepliym, зачем вы учите других писать неоптимальный код? ((((((((
1. Условие на номенклатуру делается в виртуальных параметрах, иначе сперва получаются остатки по ВСЕЙ номенклатуре, а потом из всей массы отсекается нужная номенклатура.
2. В конце обработки проведения не надо делать "ЭтотОбъект.Записать(РежимЗАписиДокумента.Проведение);"! Запись произойдет своим чередом после окончания выполнения процедуры ОбработкаПроведения().
3. "Если Отказ Тогда
        Возврат;
    КонецЕсли;"
Возврат из процедуры проведения следует делать если дальше идет какой нибудь значимый код (формирование движений и т.д.). А у вас это в конце процедуры написано. Смысл тогда?
4. Тем более запрос в цикле!!
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

Оффлайн tepliym

  • *
  • Сообщений: 24
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2014-01-28
  • Сайт: 
  • Профессия: Программист 8.1
tepliym, зачем вы учите других писать неоптимальный код? ((((((((
1. Условие на номенклатуру делается в виртуальных параметрах, иначе сперва получаются остатки по ВСЕЙ номенклатуре, а потом из всей массы отсекается нужная номенклатура.
2. В конце обработки проведения не надо делать "ЭтотОбъект.Записать(РежимЗАписиДокумента.Проведение);"! Запись произойдет своим чередом после окончания выполнения процедуры ОбработкаПроведения().
3. "Если Отказ Тогда
        Возврат;
    КонецЕсли;"
Возврат из процедуры проведения следует делать если дальше идет какой нибудь значимый код (формирование движений и т.д.). А у вас это в конце процедуры написано. Смысл тогда?
4. Тем более запрос в цикле!!
Никого я не учу, девушка обратилась с своим кодом, я сделал так что б он работал и все .


Теги:
 


* Живое общение

Не устроил ответ?

Зарегистрируйся и задай свой вопрос. Живое общение приносит результат намного быстрее.


Зарегистрироваться

* Реклама

* Поиск

* Последние задачи на разработку (фриланс)

* Реклама

* Последние вакансии

* Топ 10 авторов за месяц

Геннадий ОбьГЭС Геннадий ОбьГЭС
154 Сообщений
ilyay ilyay
66 Сообщений
alex0402
53 Сообщений
AIFrame
47 Сообщений
andron81_81
44 Сообщений
oleg-x
44 Сообщений
BuhRust
33 Сообщений
MuI_I_Ika MuI_I_Ika
32 Сообщений
Golickoff Golickoff
31 Сообщений
Dima Dddd Dima Dddd
24 Сообщений

* Кто онлайн

  • Точка Гостей: 287
  • Точка Скрытых: 0
  • Точка Пользователей: 5
  • Точка Сейчас на форуме:

* Облако тэгов

* Форум 1С с мобильного

* Инструменты

* Дополнительно

Поиск

 
SimplePortal 2.3.5 © 2008-2012, SimplePortal