Имя: Пароль:
1C
 
Как использовать процедуру во встроенном языке?
,
0 program345
 
11.02.15
14:37
доброго дня!
есть
//
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

        Если Этотобъект.Подразделение.Наименование = "МСК" Тогда
        
         ПроверитьКоличествоНаСкладе();
        
    КонецЕсли;

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


Процедура ПроверитьКоличествоНаСкладе()

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

        РезультатЗапроса = Запрос.Выполнить();
        Если РезультатЗапроса.Пустой() Тогда
            Отказ = истина;                
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры
//
каким образом вернуть Отказ = истина в процедуру При открытии?
1 program345
 
11.02.15
14:38
или в данном случае нужно использовать функцию?
2 mikecool
 
11.02.15
14:38
передай в нее Отказ, присвой в процедуре нужное значение
ваш КО
3 Сергиус
 
11.02.15
14:39
(0)Передавай туда Отказ
4 program345
 
11.02.15
14:39
код модуля объекта док реализация товаров и услуг
5 Лодырь
 
11.02.15
14:39
Передать Отказ в качестве параметра и станет возможно его изменение внутри вызываемой процедуры.
6 mikecool
 
11.02.15
14:40
первый выпуск кафедры имени Бориса Нуралиевича?
7 РеализоВано
 
11.02.15
14:41
Отказ в процедуру предлагали передавать?
8 Мыш
 
11.02.15
14:42
Отмечусь. Тож интересует вопрос.  ))))
9 Mankubus
 
11.02.15
14:42
ПроверитьКоличествоНаСкладе(Отказ)
10 Dmitrii
 
гуру
11.02.15
14:47
(0) Лучше подобный бред делать при проведении, а не перед записью.
Собственно во всех типовых эта поверка выполняется, если только в настройках параметров учета не отключен контроль отрицательных остатков.

PS Сам код - ужас, ад и кошмар. Два ненужных цикла + запрос в одном из них. Я бы за это расстреливал с последующим пожизненных лишением права открывать конфигуратор.
11 program345
 
11.02.15
14:54
в результате получилось:

//
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    
    Если Этотобъект.Подразделение.Наименование = "МСК" Тогда
        
         ПроверитьКоличествоНаСкладе(Отказ);
         Если Отказ Тогда
            
             Возврат;
            
         КонецЕсли;
    КонецЕсли;
КонецПроцедуры;

Процедура ПроверитьКоличествоНаСкладе(Отказ)

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

        РезультатЗапроса = Запрос.Выполнить();
        Если РезультатЗапроса.Пустой() Тогда
            Отказ = Истина;                    
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры // ПроверитьКоличествоНаСкладе()

// (10) согласен, нужна оптимизация
12 program345
 
11.02.15
14:56
(10) задача контроля остатков нужна для определенного подрзделения
13 bodri
 
11.02.15
14:58
Можно строки в запрос и потом выборка по результату запроса, так на мой взгляд быстрее должно работать
14 Dmitrii
 
гуру
11.02.15
15:01
(12) Сути га..нокода это не меняет.
Задача таким образом не решается. Бывает, что пользователю надо просто записать (не проводить!) документ с неверными данными (потом дозаполнит документ правильно). А вы ему вывалите Отказ. Бред.
Остатки должны контролироваться при проведении, а не при записи.
15 Dmitrii
 
гуру
11.02.15
15:03
+ к (14) Позвали бы вы специалиста чтоли....
16 kosts
 
11.02.15
15:33
(12) По свежей методике если не ошибаюсь, остатки надо проверять после проведения. И если превысили, то делать откат.
17 program345
 
12.02.15
07:57
В итоге:

//

    Если Этотобъект.Подразделение.Наименование = "МСК" Тогда
        
         ПроверитьКоличествоНаСкладе(Отказ);
         Если Отказ Тогда
             Сообщить("Нельзя в документе ""Реализация товаров и услуг"" указывать товара больше, чем его есть в базе данных!");
             Возврат;
            
         КонецЕсли;
    КонецЕсли;


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

        РезультатЗапроса = Запрос.Выполнить();
        Если РезультатЗапроса.Пустой() Тогда
            Отказ = Истина;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры // ПроверитьКоличествоНаСкладе()

//

Записывать док можно с любыми данными, а каким образом можно передать в запрос всю номенклатуру с количеством (из табл. части документа),  чтобы вызывать сервер 1 раз?
18 Mankubus
 
12.02.15
08:06
(17) делай запрос сразу по таблице товары. зачем еще ТаблЗн создавать?
19 program345
 
12.02.15
08:34
(18) Таблицу значений создал с целью передать в запрос сразу несколько значений номенклатуры и количества. Но что-то пошло не так...
а так конечно проще:

//
Процедура ПроверитьКоличествоНаСкладе(Отказ)

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

        РезультатЗапроса = Запрос.Выполнить();
        Если РезультатЗапроса.Пустой() Тогда
            Отказ = Истина;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

//
20 chelentano
 
12.02.15
08:35
(19) какой кошмар
21 MrKartez
 
12.02.15
08:51
Создание ТЗ вынеси за цикл, она у тебя каждый раз новая и пустая создается же
22 vde69
 
12.02.15
08:53
приведу критику

1. добавь реквизит и слелай так Если Этотобъект.Подразделение.КонтролироватьОстатки = Истина Тогда, тогда контроль будет настраиваемый в пользовательском режиме....

2. на складе 10шт, в документе 2 строки 7 и 8шт, твой код ДАСТ списать в минус!!!, именно по этому 1с сейчас рекомендует такие проверки делать ПОСЛЕ записи и проведения...

3. сам запрос - условие перенеси в параметры виртуальной таблицы, будет в разы быстрее...
23 program345
 
12.02.15
08:54
(21) согласен
24 Escander
 
12.02.15
08:58
(0) вариант1 - передать туда отказ параметром и там его сделать равным Истина.
вараинт2 - сделать из процедуры функцию и присваивать возвращаемое в Отказ
25 vde69
 
12.02.15
09:11
(24) вариант 2 не верный, по тому как Отказ может быть установлен ранее вызова функции и она тогда может затереть этот флаг...
26 Mankubus
 
12.02.15
09:15
(19) >>передать в запрос сразу несколько значений номенклатуры и количества
ну и где ты СРАЗУ несколько передаешь? я вижу только что каждая строка по отдельности передается
27 VladZ
 
12.02.15
09:18
О Боже мой!  Как мне это развидеть обратно????
28 vde69
 
12.02.15
09:21
29 Serg_1960
 
12.02.15
09:29
(25) Вариант 2 - тоже нормальный. Все зависит от того, как и когда присваивать значение.

// Вариант А
Отказ = ?(ПроверитьКоличествоНаСкладе(), Истина, Отказ);

// Вариант Б
Функция ПроверитьКоличествоНаСкладе(Отказ)

   Если Не Отказ Тогда
      ...
   КонецЕсли;

Возврат Отказ;
30 Ненавижу 1С
 
гуру
12.02.15
09:32
(22) >>менно по этому 1с сейчас рекомендует такие проверки делать ПОСЛЕ записи и проведения

не поэтому
31 chelentano
 
12.02.15
09:34
(22) я бы ещё добавил, что не стоит делать отбор по наименованию номенклатуры, по слухам - гораздо лучше по ссылке
32 VladZ
 
12.02.15
09:34
(28) Ё...  Кардинально.
33 vde69
 
12.02.15
09:35
(30) рекомендует из-за скорости, но скорость понятие относительное, зависит как от конкретной реализации так и от скорости ролбака конкретной субд, кроме того этот подход позволяет получить все уведомления проведения а не обрезаный кусок....

но это литрики, для автора это не имеет значения :)