Имя: Пароль:
1C
1C 7.7
v7: Как рассчитать конечный остаток регистра
0 exec11
 
02.06.23
12:41
V.77 !!!

Все доброго дня !

Есть регистр "ПоПартиям" по типу Остатки.
У него есть Ресурсы : Остаток

Как при проведение документа, в модуле документа, рассчитать конечный "Остаток" на момент проведения документа ?
1 dedmoroz777
 
02.06.23
12:49
Остаток(<?>,)
Синтаксис:
Остаток(<Измерен1>,<Измерен2>...,<ИмяРесурса>)
Назначение:
Возвращает значение остатка заданного ресурса регистра.
Параметры:
<Измерен1>,<Измерен2>... - значения измерений регистра;
<ИмяРесурса> - название требуемого ресурса регистра.
Замечание:
Метод используется только для регистров остатков.
2 Bigbro
 
02.06.23
12:50
рассчитатьрегистрына документ
и добавить то что в документе.
3 exec11
 
02.06.23
13:00
(1)
РенПоПартиям=СоздатьОбъект("Регистр.ПоПартиям");
Если ИтогиАктуальны()=0 Тогда
    РенПоПартиям.ВременныйРасчет(1);  
    РассчитатьРегистрыПо(ТекущийДокумент());        
КонецЕсли;
                                            
РенПоПартиям.Договор        = Договор;  
РенПоПартиям.Номенклатура   = Товар;

ТекОстаток = РенПоПартиям.Остаток(,,Товар,,,,Договор,"Остаток");
Сообщить(" ТекОст    "+ТекОстаток);

----
ТекОст 0
4 Bigbro
 
02.06.23
13:05
(3) в этом случае у вас будет разный результат
когда проводим новый документ
и перепроводим уже проведенный.
5 exec11
 
02.06.23
13:08
(4)
Как сделать ?
6 Builder
 
02.06.23
13:12
(5) РассчитатьРегистрыНа(ТекущийДокумент())
7 exec11
 
02.06.23
13:16
(6)
Исправил.

Конечный остаток не рассчитывается:
----
ТекОст 0
8 Bigbro
 
02.06.23
14:16
я же написал в (2)
что непонятного?
9 Харлампий Дымба
 
02.06.23
14:25
.СводныйОстаток(
10 exec11
 
05.06.23
11:25
(8)
Не рассчитывает. Мой код в (3)
Код верный ?

(9) Тоже что то не получилось.
Можете написать пример кода ?

Из ИТС (наверное) есть отчет по регистрам.
Там много строк.
Те строки где поле документ (все) КонОст не ноль.
Те строки где есть документ указан, КонОст равен нулю.
В код этого отчета залезть пробовал, но там все динамическое. Пока уровень феншуя не позволяет понять, как этот отчет высчитывает КонОст.
11 uno-group
 
05.06.23
11:38
(10) Если не указываешь все измерения то получаешь не остатком а сводным остатком.
Или устанавливаешь фильтры по измерениям и делаешь выгрузить итоги.
12 Злопчинский
 
05.06.23
11:58
почему РассчитатьРегистрыПо
а не РассчитатьРегистрыНа
?
13 Злопчинский
 
05.06.23
12:00
открой типовую ТиС, посмотри модуль проведения Реализации или Заяки
.
РенПоПартиям.Договор        = Договор;  
РенПоПартиям.Номенклатура   = Товар;
- это для получеия остатка - зачем?
14 exec11
 
05.06.23
12:08
(12) Исправил На - результат тот же.
(13) Часть кода осталась с другого варианта рассчитать остаток.
Не знаю как теперь поправить удалить эти все строки.
Заметил только когда отправил.
15 exec11
 
05.06.23
12:10
(14) не "эти все строки", а "эти две строки"
16 Харлампий Дымба
 
05.06.23
13:15
Просто не видно же что ТС нужно. Так-то в модуле проведения СводныйОстаток() очень редко когда нужен, ну может для контроля остатков только в целом по холдингу. А для работы с себестоимостью или нормальным закрытием регистров нужен Остаток(). Ну или можно через ВыгрузитьИтоги(), или ОстаткиПолучить(). Тут уже вкусовщина - удобство - скорость - конкретные условия. Мне вот удобнее было использование ОстактиПолучить(). Ну навскидку по памяти:

    Регистры=СоздатьОбъект("Регистры");
    Регистры.Актуальность(1);
    Рег=Регистры.Остатки;
    Если ИтогиАктуальны()=0  Тогда
        Рег.УстановитьЗначениеФильтра("Фирма",Фирма,1);
        Рег.УстановитьЗначениеФильтра("Склад",Склад,1);
        СписокТоваров = СоздатьОбъект("СписокЗначений");
        ВыгрузитьТабличнуюЧасть(СписокТоваров, "Товар");
        Рег.УстановитьЗначениеФильтра("Товар",СписокТоваров,2);
        Рег.ВременныйРасчет();
        Регистры.РассчитатьРегистрыНа(ТекущийДокумент());
    КонецЕсли;
//либо: порядок не важен, заполненность можно важна/не важна (можно пропускать измерения), удобнее если ресурсов несколько.
    Рег.Фирма=Фирма;
    Рег.Товар=Товар;
    Рег.Склад=Склад;
    Рег.ОстаткиПолучить();//удобно, что рассчитываешь остатки по всем ресурсам сразу
    Остаток=Рег.Количество;
    СтоимостьОстатка=Рег.Стоимость;
//либо: порядок и заполненность важны! быстро
    Остаток=Рег.Остаток(Фирма,Товар,Склад,"Количество");
//либо: порядок важен, заполненность неважна! долго
    Остаток=Рег.СводныйОстаток(Фирма,Товар,Склад,"Количество");
17 Харлампий Дымба
 
05.06.23
13:24
//через таблицу значений, вот ещё кусок кода нашел где-то
        Регистры=СоздатьОбъект("Регистры");
        Рег=Регистры.Остатки;
        Рег.УстановитьЗначениеФильтра("Фирма",Фирма,1);
        Рег.УстановитьЗначениеФильтра("Склад",Склад,1);
        СписокТоваров = СоздатьОбъект("СписокЗначений");
        ВыгрузитьТабличнуюЧасть(СписокТоваров, "Товар");
        Рег.УстановитьЗначениеФильтра("Товар",СписокТоваров,2);
        Если (СравнитьТА()=-2)и(ДатаДок<ПолучитьДатуТА()) Тогда  // новый
            Рег.ВременныйРасчет();
            Регистры.РассчитатьРегистрыПо(ДатаДок);
        ИначеЕсли СравнитьТА()=-1 Тогда  // док раньше ТА
            Рег.ВременныйРасчет();
            Регистры.РассчитатьРегистрыНа(ТекущийДокумент());
        КонецЕсли;    
        ТаблицаИтогов=СоздатьОбъект("ТаблицаЗначений");
        Рег.ВыгрузитьИтоги(ТаблицаИтогов,НужныЛиКолонкиСоЗначениямиИзмерений);
18 exec11
 
05.06.23
14:10
(16)
Адаптировал под себя.

        // ------                        
        Регистры=СоздатьОбъект("Регистры");
        Регистры.Актуальность(1);
        Рег=Регистры.ПоПартиям;
        Если ИтогиАктуальны()=0  Тогда
            Рег.УстановитьЗначениеФильтра("Договор",Договор,1);
            Рег.УстановитьЗначениеФильтра("Номенклатура",Товар,1);
            //СписокТоваров = СоздатьОбъект("СписокЗначений");
            //ВыгрузитьТабличнуюЧасть(СписокТоваров, "Товар");
            //Рег.УстановитьЗначениеФильтра("Товар",СписокТоваров,2);
            Рег.ВременныйРасчет();
            Регистры.РассчитатьРегистрыНа(ТекущийДокумент());
        КонецЕсли;
        
        Рег.Договор=Договор;
        Рег.Номенклатура=Товар;
        Рег.ОстаткиПолучить();
        ТекОстаток1 = Рег.Остаток;
        ТекОстаток2 = Рег.Остаток(,,Товар,,,,Договор,"Остаток");
        Сообщить("ТекОстаток1  "+ТекОстаток1)
                Сообщить("ТекОстаток2  "+ТекОстаток2);
----
ТекОстаток1 0
ТекОстаток2 0
19 exec11
 
05.06.23
14:16
(18) Должно рассчитывать. Но все по нулям. Вот сижу смотрю, что не так. Пока не вижу.

Переходить к варианту (17)  ?
20 uno-group
 
05.06.23
14:16
Рег.Остаток(,,Товар,,,,Договор,"Остаток"); не допускает пустых измерений
Рег.СводныйОстаток() Допускает пустые измерения в конце тоесть указываешь измерение 1,2,3  а 4, 5 может быть пустым
21 uno-group
 
05.06.23
14:18
Тоесть ты фактически получаешь сейчас остатки по фирме="" и по складу равному="". конечно у тебя на такой фирме и складе ничего не числиться
22 exec11
 
05.06.23
14:28
(20)
(,,Товар,,,,Договор,"Остаток")
Может, что то я не до понимаю. Уточню:  

        Регист ПоПартия:
        Измерения:
        Счет
        ВидТовара
        Номенклатура
        Документ
        вРамкахСчета
        СчетУчета
        Договор
        
        Ресурсы:
        Остаток
        НакоплСтоимость

(,1,Товар,,,,Договор,"Остаток")
Место где стоит "1" - это "Счет" имеется ввиду.
В моем фильтре он может быть любой. Поэтому ничего не указываем.
Получается ,,
23 exec11
 
05.06.23
14:33
Запись в регистр производится так, из модуля документа :

        -------------------
    Регистр.ПоПартиям.вРамкахСчета    = вРамкахСчета;
    Регистр.ПоПартиям.Счет            = Счет;                  
    Регистр.ПоПартиям.Договор         = Договор;
    Регистр.ПоПартиям.СчетУчета       = СчетУчета;                    
    Регистр.ПоПартиям.ВидТовара       = ВидТовара;
    Регистр.ПоПартиям.Номенклатура    = Товар;
    Регистр.ПоПартиям.Документ        = ТекущийДокумент();
    Регистр.ПоПартиям.Остаток         = Количество;  
    Регистр.ПоПартиям.НакоплСтоимость = Количество*ЦенаРуб;  
    Регистр.ПоПартиям.ДвижениеПриходВыполнить();
24 uno-group
 
05.06.23
14:34
(22) тогда только через выгрузку итогов в таблицу. и подсчет отстатков по списку всех счетов или через ТзОстатки.итог("Остаток);
Изначально созданна неправильная структура регистра первыми должны идти измерения которые извесетны потом те которые плавают
25 uno-group
 
05.06.23
14:38
Если так во всех документах то у тебя еще этот регистр нефига не закрывается и пухнуть будет со страшной силой.
Регистр.ПоПартиям.Документ        = ТекущийДокумент();
Половина из этих измерений вообще в реквизиты проситься.
26 uno-group
 
05.06.23
14:42
Может тебе к этому регистру подтянуть регистр остатков и остаток по нему контролировать?
там измерений меньше должно быть
27 exec11
 
05.06.23
15:10
Измерения создавались по мере необходимости.
Сам код зависит от последовательности измерений.
Поэтому получается так.
Не, можно конечно пересортировать все измерения. А надо ?

Можно создать другой регистр. Но.
Сейчас я хочу высчитать среднюю цену товара на каждый приход и расход самого товара.

Нужен регистр по партия. Ну он и есть. Добавили ресурс Накопленная стоимость.
Теперь по сути надо высчитать при проведении остаток и накопленную стоимость, поделить их друг на друга и должно быть счастье.
А его нету. Что то не высчитывается как должен.

Сейчас все таки по мучаюсь чуток, и что нибудь через костыль приделаем.
Ну чо он не рассчитывается !! Должен ведь. Заводить новый регистр с меньшим числом измерений ?
28 uno-group
 
05.06.23
15:15
Что такое Счет, Договор, СчетУчета зачем они тут. такое впечатление что человек который только бух знает создавал регистр по аналогии.
29 exec11
 
05.06.23
15:30
Это поля для запросов в отчетах, по ним нужны итоги. Их можно было считать в ручную, кодом. А можно в запрос за один проход. Отчетов много. Разрезов и детализаций тоже много. Вот и подросли измерения.

Конфигурация самописная. Художник я сам. Решаю задачи по мере поступления.
30 Харлампий Дымба
 
05.06.23
16:20
(18) Выглядит нормально... А точно есть ненулевой остаток по количеству по договору и товару?
Ну и попробуй 17
Рег.ВыгрузитьИтоги(ТаблицаИтогов,1);
ТаблицаИтогов.ВыбратьСтроку();  - покажет что-нибудь?

Ну и (25) люто плюсую. 7 измерений, причем потенциально последнее (Документ) вряд ли закрывается, судя по исходному вопросу. Итого 7 факториал записей в таблице итогов на каждый товар каждый месяц. А если ещё "для скорости" стоят галки "Отбор итогов" или период оперативных итогов 5 дней... Не очень хорошо будет.
31 Харлампий Дымба
 
05.06.23
16:22
к (30) не, про факториал я погорячился. Ну суть та же
32 Злопчинский
 
05.06.23
16:23
Счёт и Договор также несколько напрягают... Да ещё ВРамкахСчета
33 Харлампий Дымба
 
05.06.23
16:24
(32) Голосую за "в реквизиты!"
34 Харлампий Дымба
 
05.06.23
16:25
(32) а ВидТовара при живом Товаре?
35 uno-group
 
05.06.23
16:52
(29) что мешает в запросе написать. ВидТовара=Регистр.Партии.ВидТовара или запихнуть это в измерение в крайнем случае. Попробуй почитать хотя бы 1 книжку по теории баз данных чем что то программировать.
36 uno-group
 
05.06.23
16:53
+35 ВидТовара=Регистр.Партии.Товар.ВидТовара
37 Bigbro
 
05.06.23
21:09
ТекОстаток = РенПоПартиям.Остаток(,,Товар,,,,Договор,"Остаток");
Сообщить(" ТекОст    "+ТекОстаток);

это тоже в модуле проведения?
38 exec11
 
06.06.23
11:30
(37) Да, весь код в модуле проведения.

Попробовал сделать как в (17), дописал это.

        ТаблИтогов=СоздатьОбъект("ТаблицаЗначений");
        Рег.ВыгрузитьИтоги(ТаблИтогов,1,1);
        ТаблИтогов.ВыбратьСтроки();
        КонОст       =0;
        КонСтоимость =0;  
        Пока ТаблИтогов.ПолучитьСтроку()>0 Цикл
            КонОст       =КонОст        + ТаблИтогов.Остаток;    
            КонСтоимость = КонСтоимость + ТаблИтогов.НакоплСтоимость;
        КонецЦикла;
        КонОст       = КонОст       +Количество;
        КонСтоимость = КонСтоимость + Количество*Цена;
        Сообщить("КонОст  "+КонОст);
        Сообщить("КонСтм  "+КонСтоимость);
        Сообщить("СрЦен  "+КонСтоимость/КонОст);

В принципе, как то считает.
Полазил в инет, нашел :
Временный расчет регистра остатков

Кто то так же как я бился еще в 2013 году.
Костыль - ну да ладно. Кто то скажет ну это ж 77.

Другого расчета так понимаю нету ?
39 Bigbro
 
06.06.23
11:37
(38) а что ты ожидал увидеть в модуле проведения когда движения текущего документа еще не сформированы?
ты там и получаешь конечный остаток на момент ДО проведения документа.
потому что момент проведения документа - еще не наступил.
тут нет процедуры ПослеПроведения

по итогу ты сделал ровно то что я написал в (2)
получил остаток на документ и добавил то что в документе.
40 exec11
 
06.06.23
12:03
(39) Ну скажем так, хотелось бы ПолучитьКонОст() на предыдущий документ. Это же регистр !
В запрос есть функция Конечный остаток ? Ну вот что то вроде этого хотелось.
А в итоге все свелось к пересчету в цикле. То же конечно вариант. Но мы ж художники, нам подавай красоту решений !
:)
41 Харлампий Дымба
 
06.06.23
12:26
(40) Так ты и получаешь конечные остатки по предыдущий документ включительно. Ну или начальные остатки на текущий документ. А вот какой смысл в остатке после проведения документа в модуле проведения документа - я не знаю, и восхищён  Bigbro, который уже в (2) увидел то, что я и сейчас не вижу в исходном вопросе: желание получить итоги с учетом проведения текущего документа.
Ну и в любом случае в 7.7  всё это есть: Регистры.Актуальность(1) будет поддерживать остатки в актуальном состоянии. То есть получил остаток до, сделал движение регистра, получил остаток уже с учетом этого движения.
42 uno-group
 
06.06.23
12:54
(38) При чем тут 7.7 если у тебя знаний не хватает и криво создана структура базы данных. и вместо того чтобы ее исправить ты делаешь очередные костыли.
Нафига цикл если ты складываешь без дополнительных условий.
КонОст=ТаблИтогов.Итог("Остаток");
КонСтоимость=ТаблИтогов.Итог("НакоплСтоимость");
СрЦен =?(КонОст=0,0,КонСтоимость/КонОст);
43 uno-group
 
06.06.23
13:00
Тебе 20 раз написали, что если пропускаешь и не указываешь какие то измерение, то надо писать не "остаток", а "сводный остаток"
ТекОстаток2 = Рег.СводныйОстаток(,,Товар,,,,Договор,"Остаток");
44 exec11
 
06.06.23
13:24
(42) Да, со всеми утверждениями согласен.
Заменил цикл на Итог.
45 Bigbro
 
06.06.23
13:29
(41) просто я видел много разного... ;%ма, и самому порой такое колхозить приходилось.. что только обнять и плакать)
и задача получить результат проведения до проведения - это еще не самое яркое)
46 exec11
 
06.06.23
14:34
(45) Так обычно и бывает.
В какой то момент начинаешь задумываться о цикле жизни проекта (на пример базы в нашем случае)

Все начиналось с екселя. Замучилась. Взяли 77 как ексель чуть по сложнее.
Пошли от простого. Так и так.
Ага появились новые вводные.
Надо переделать. Вот так. А то удалить ?
А если удалить, то и то перестанет работать.
Надо переделать на новый регистр. Не охота.
Много ресурсов ? Криво ? Да.
Но пока не прижмет, не хочется править. Так и живем.
Что будет дальше ? Какие законы финансовые примут ? Никто не знает.
Поэтому из ходим из того что есть.
47 Злопчинский
 
06.06.23
14:53
(46) "Хрен ли думать, трясти надо!"
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой