Имя: Пароль:
1C
1С v8
Контроль остатков из регистра
,
0 Dmitriyspbs
 
01.09.22
19:29
Добрый день, программист начинающий, так что не кидайте камни сразу))
Суть задачи такая: Есть регистр накопления (остатки) "Движения денежных средств", Есть документ "Списание денежных средств", Справочник "Счета контрагентов" с иерархией по элементам.
Дело такое: в справочнике есть например счет контрагент 01, ему подчинен счет 0101 и т.д. на все эти счета может регистрироваться и приход и расход. С помощью документа приход добавляю на счет 01- тысячу рублей, на счет 0101 тысячу, в итоге на контр-агенте 2000 рублей. Нужно реализовать контроль отрицательных остатков, что бы со счета контр-агента нельзя было списать больше чем у него есть.
С помощью запроса получил сумму всех поступлений контр-агента по иерархии         
                |ИТОГИ
        |    СУММА(СуммаОстаток)
        |ПО
        |    СчетКонтрагента ИЕРАРХИЯ
Запрос организовал так что бы показывал отрицательный остаток у контр-агента. Реализовал функцию и процедуру.

Функция ПроверитьОтрицательныйБаланс(СчетКонтрагента, ДатаОтбора) Экспорт
    
    ГраницаОтбора    = Новый Граница(ДатаОтбора, ВидГраницы.Включая);
    
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ДвиженияДСОстатки.СчетКонтрагента КАК СчетКонтрагента,
        |    ДвиженияДСОстатки.СуммаОстаток КАК СуммаОстаток
        |ИЗ
        |    РегистрНакопления.ДвиженияДС.Остатки(
        |            &ДатаОтбора,
        |            Контрагент В
        |                (ВЫБРАТЬ
        |                    СписаниеДССписаниеДС.Контрагент КАК Контрагент
        |                ИЗ
        |                    Документ.СписаниеДС.СписаниеДС КАК СписаниеДССписаниеДС
        |                ГДЕ
        |                    СписаниеДССписаниеДС.СчетКонтрагента = &СчетКонтрагента)) КАК ДвиженияДСОстатки
        |ГДЕ
        |    ДвиженияДСОстатки.СуммаОстаток < 0
        |ИТОГИ
        |    СУММА(СуммаОстаток)
        |ПО
        |    СчетКонтрагента ИЕРАРХИЯ";

    
    Запрос.УстановитьПараметр("ДатаОтбора", ГраницаОтбора);
    Запрос.УстановитьПараметр("СчетКонтрагента", СчетКонтрагента);
    
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой()=Истина Тогда
          Возврат Ложь;
    КонецЕсли;
    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        СтрокаВывода    = СтрШаблон("Для списания не хватает суммы в размере: %1, на счету контрагента %2", ВыборкаДетальныеЗаписи.СуммаОстаток, ВыборкаДетальныеЗаписи.Контрагент);
        Сообщить(СтрокаВывода);    
    КонецЦикла;
    Возврат Истина;
КонецФункции // ПроверитьОтрицательныйБаланс()


И в документе "СписаниеДС" обработка проведения:


Процедура ОбработкаПроведения(Отказ, Режим)
    //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

    // регистр ДвиженияДС Расход
    Движения.ДвиженияДС.Записывать = Истина;
    Для Каждого ТекСтрокаСписаниеДС Из СписаниеДС Цикл
        Движение = Движения.ДвиженияДС.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Контрагент = ТекСтрокаСписаниеДС.Контрагент;
        Движение.СчетКонтрагента = ТекСтрокаСписаниеДС.СчетКонтрагента;
        Движение.Сумма = ТекСтрокаСписаниеДС.Сумма;
    КонецЦикла;
    
    //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    
    Движения.ДвиженияДС.Записать();
    Отказ    = РегистрыНакопления.ДвиженияДС.ПроверитьОтрицательныйБаланс(ЭтотОбъект.Ссылка, ЭтотОбъект.Дата);
        
КонецПроцедуры


Но если проводить документы "СписаниеДС" на суммы больше чем есть у контрагента, они все равно проводятся и остаток уходит в минус. Делал идентичный код для товаров, в которых иерархия идет как группы и элементы, все работало. Тут где иерархия элементов, ничего не получаеться. Подскажите как решить проблему
1 Dmitry1c
 
01.09.22
20:12
>>Есть регистр накопления (остатки) "Движения денежных средств",


у тебя в кошельке тоже движения лежат?

сколько остатков движений у тебя в кошельке ?
2 Dmitriyspbs
 
01.09.22
20:34
(1) Не понял что за кошелек? У меня получается в регистр записываются сведения из двух документов: Проход "ПоступлениеДС" и расход "СписаниеДС". Например у одного контрагента счет основной 01, далее по иерархии 0102, 0103, далее 010201, 010203 и так до бесконечность можно растить это дерево. На каждый из счетов я положил по 1000р., включая и счет первого родителя 01. Но что бы списать деньги со счета контрагента, на его основном счету 01, должна проверяться сумма всех счетов, если она достаточна списывается, не важно с 01 или 0102, но если на всех его подсчетах в сумме не хватает денег для списания, нужно запретить проведение документа и выдать ошибку что у контрагента не хватает средств на счету.
Запросом я получил отрицательный остаток, и записал его в обработку проведения
3 Злопчинский
 
01.09.22
20:36
Счет - измерение регистра должен быть.
и нахер здесь нужна иерархия элементов в справочнике счетов? (справочник счетов тупо как перечень значений измерения "счет")
4 Злопчинский
 
01.09.22
20:40
смысл приходовать на 0102, а списывать с 01..?
ты не попутал стучайно статьи движения денежных средств (обороты) с остатками..?
и что такое "Счет" - счет - это документ или счет в терминах расчетных/банковский счетов?
.
изложи задачу внятно (что нужно сделать), не привязываясь (нахер как надо сделать!!!) к объектам 1С.
.
я вот прочитав бегло нихера не понял идеи/концепции ведения твоего учета...
когда будет понятно что надо сделать - тогда и выбирать "как"
5 Dmitry1c
 
01.09.22
20:47
(2) обычный кошелек.

зачем ты назвал регистр "движения", если у тебя в нем "остатки"? назови "Денежные средства".
6 Злопчинский
 
01.09.22
21:00
(5) а нахера обычный кошелек делится на "подкошельки" какие-то?
7 DCKiller
 
01.09.22
21:12
(0) Мож тебе еще и по счету надо отбор в запросе к таблице остатков регистра делать, а не только по контрагенту?
8 DCKiller
 
01.09.22
21:17
+И кстати, вот это вот

"Контрагент В
        |                (ВЫБРАТЬ
        |                    СписаниеДССписаниеДС.Контрагент КАК Контрагент
        |                ИЗ
        |                    Документ.СписаниеДС.СписаниеДС КАК СписаниеДССписаниеДС
        |                ГДЕ
        |                    СписаниеДССписаниеДС.СчетКонтрагента = &СчетКонтрагента)"

не подразумевает, что нужно ограничить выборку конкретным текущим документом списания ДС (тем, у которого у тебя вызывается функция с этим запросом в обработке проведения)?
9 Dmitriyspbs
 
01.09.22
23:26
(7) Кстати да, я пробовал либо по контрагенту делать, либо по счету контрагента. Как-то вместе не догадался, попробую сделать, спасибо за наводку))
10 Dmitriyspbs
 
02.09.22
10:58
(6) По тех заданию кошелки делятся