Имя: Пароль:
1C
1C 7.7
v7: Быстрой способ получения долга контрагента
,
0 zenon46
 
23.08.18
13:03
Доброго дня!
Подскажите пожалуйста, какой самый быстрый способ (программный), получить долг контрагента, дело в том что нужно выводить эту информацию на печатной форме, да еще в разных местах, пытаюсь выяснить каков способ/алгоритм будет наиболее эффективный?
База 7.7 комплексная.
1 abibas
 
23.08.18
13:14
Самый простой и довольно быстрый - использовать функцию глобального модуля глТекущийДолг(Фирма, Договор, Роль). Самый быстрый - прямой запрос.
2 zenon46
 
23.08.18
13:31
(1) глТекущийДолг - тут засада в том что с контрагентом может быть огромное количество договоров, придется в цикле их все перебирать.
3 DexterMorgan
 
23.08.18
13:34
"Быстрой способ получения долга контрагента"

Имхо, лучше пистолета ничего не придумали
4 zenon46
 
23.08.18
13:36
(3) ))))) как вариант
5 Масянька
 
23.08.18
13:40
(2) В таком варианте:

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

КонецФункции // глТекущийДолг()


выводит общий долг.
6 zenon46
 
23.08.18
14:38
(5) а как в таком варианте определить контрагента ?
7 Базис
 
naïve
23.08.18
14:54
(6) По договору. И вообще, открой почти любой документ в пользовательском режиме, увидишь рядом с полем "Контрагент" кнопку вывода текущего долга.
8 zenon46
 
23.08.18
14:59
(7) в том и дело, долг скопом получить по ВСЕМ договорам сразу, возможно ли такое? Без перебора договоров в цикле.
9 Базис
 
naïve
23.08.18
15:08
Блин! Ну посмотри же ты структуру данных, если там в разрезе договоров - то нет, только суммировать по всем. А уж кто будет суммировать - готовый код, твой запрос или Маринка - выбор за тобой.
10 zenon46
 
23.08.18
15:09
(9) в регистрах только в разрезе договоров. Вопрос в том и состоял найти самый быстрый способ.
11 zenon46
 
23.08.18
15:10
(5) а в (5) закоментили строку, кинули строку с убранным договором, так будет только по всем контрагентам скопом.
12 Aleksey
 
23.08.18
16:15
(8) Получи список договоров запросом, раз не нравиться перебор в цикле
13 Glup0sti
 
23.08.18
16:20
утюг..., но правда не программный
14 unregistered
 
23.08.18
16:22
ОФФ.

(0) > Быстрой способ получения долга контрагента

Быта, утюг и паяльник.
Иногда легче переуступить право долга пацанам, которые в совершенстве владеют этими инструментами.
15 zenon46
 
23.08.18
17:00
А вот этот запрос можно как то ускорить? Суть его в том что бы получить все НЕПРОВЕДЕННЫЕ документы за период. Может кто подскажет как его на прямой переписать, и будет ли в этом толк.
        Запрос = СоздатьОбъект("Запрос");
        ТекстЗапроса = "
        |Период с НачДата по КонДата;
        |ОбрабатыватьДокументы Непроведенные;
        |ТекДок                        = Документ.Реализация.ТекущийДокумент;
        |ФирмаЗ                       = Документ.Реализация.ТекущийДокумент.Фирма;
        |Контр                         = Документ.Реализация.ТекущийДокумент.Контрагент;
        |СумОтгруз                    = Документ.Реализация.ТекущийДокумент.СуммаВзаиморасчетов;
        |Группировка ТекДок;
        |Условие (ТекДок.ПометкаУдаления() = 0);
        |Условие (ФирмаЗ = Фирма);
        |Условие (Контр = Контрагент);
        |";
        Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
            Возврат(0);
        КонецЕсли;
16 Карст
 
23.08.18
17:08
ахренеть , долг по документам Оо
17 Карст
 
23.08.18
17:08
блин аж напугал ))))
18 Базис
 
naïve
23.08.18
17:20
(17) И нормально работало. Ну, если первичка вносилась своевременно, а порядок закрытия по ФИФО. Взяли сумму долг  а из регистра и пошли складывать-вычитать с конца.
19 Масянька
 
23.08.18
17:34
Если в регистре, где ведутся взаиморасчеты, нет контрагента и ведете по договорам - не просто.
Как вариант, смотреть по счету - не знаю, есть в комплексной план счетов и регистр бухгалтерии.
20 zenon46
 
23.08.18
19:58
(16) ты не понял, долг по регистрам, а это что бы прибавить непроведенные документы (есть нюансы в учете, документы проводятся в конце месяца, ибо в конфигурации реализована работа схема агент-принципал).
21 Kigo_Kigo
 
23.08.18
20:30
не я все понимаю, но суммировать движение регистра взаиморасчетов с не проведенными документами- тот еще гемор, договора запихнуть в список значений и по нему делать запрос, проблем ноль
22 Злопчинский
 
23.08.18
20:48
//Здесь сформировать выборкой СЗ с договорами контрагента, СЗдоговор
Рег.УстановитьЗначениеФильтра("Договор",СЗдоговор,2);
Рег.СводныйОстаток(Фирма,,,,"Сумма"); //количество неуказанных измерений по зпт

По идее - должно работать... Договор с водном остатке не задаем, типа получаем ПО ВСЕМ ДОГОВОРАМ вообще всех контрагентов.. но тут - чебурашечный - финт список договоров ограничиваем !фильтром!

Но сам я такую конструкцию не применял, так что надо потестить, тест простейший
23 Злопчинский
 
23.08.18
20:52
Ставлю процентов 80, что проканает
24 Злопчинский
 
23.08.18
21:09
.. потестил.. хрен нам.. не работает такой финт.. пичалька...
25 NSSerg
 
23.08.18
22:30
(22)
рег.УстановитьЗначениеФильтра(  
рег.ВыгрузитьИтоги(ТабИтогов
ТабИтогов.Итог(
26 NSSerg
 
23.08.18
22:46
//*******************************************
Процедура Сформировать()    
    СЗДоговор=создатьобъект("СписокЗначений");
    Запрос=создатьобъект("Запрос");
    ТекстЗапроса="обрабатывать все;
    |дог=справочник.договоры.текущийэлемент;
    |контр=справочник.Договоры.владелец;
    |Условие (контр=Контрагент);
    |группировка дог без групп;";
    Запрос.Выполнить(ТекстЗапроса);    
    ТЗ=создатьОбъект("ТаблицаЗначений");
    Запрос.выгрузить(ТЗ,0,0);  
    ТЗ.выгрузить(СЗДоговор,,,"дог");
    ОбщРег = СоздатьОбъект("Регистры");
    Рег = ОбщРег.Покупатели;  
    Рег.УстановитьЗначениеФильтра("Договор",СЗдоговор,2);
    ВремТабл=создатьобъект("ТаблицаЗначений");
    Рег.ВыгрузитьИтоги(ВремТабл,1,1);
    Долг = ВремТабл.Итог("СуммаРуб");
    сообщить(Долг);
КонецПроцедуры
27 Попытка1С
 
23.08.18
22:48
(0) подключи класс прямойзапрос.

у меня выводится прямым, в УПД.
28 NSSerg
 
23.08.18
22:53
Но запрос должен быть быстрее
Вряд ли у тебя база больше чем у меня.
По контрагенту с несколькими сотнями договоров.
//*******************************************
Процедура Сформировать()    
    Запрос=создатьобъект("Запрос");  
    ТекстЗапроса="
    |контр=регистр.покупатели.Договор.Владелец;
    |сумруб=регистр.Покупатели.СуммаРуб;
    |Условие (контр=Контрагент);
    |Функция Долг=Коност(сумруб);";
    Запрос.Выполнить(ТекстЗапроса);    
    сообщить(Запрос.Долг);
КонецПроцедуры
У меня выполняется 0,5 секунды
29 NSSerg
 
23.08.18
22:55
Только у меня на измерении договор стоит галочка "отбор итогов" - индекс.
И в покупатели, и в поставщики.
30 zenon46
 
24.08.18
09:24
(28) база 40 гигов, только в запросе получим долг по "покупателю", а где гарантии что нет его в "поставщиках", думаю еще туда надо включить регистр поставщики.
31 NSSerg
 
25.08.18
02:22
(30) Так включи, хотя ИМХО это не совсем верно.
главное, чтоб быстро работало - (29) - отбор итогов по договору.
32 Cthulhu
 
25.08.18
11:30
Переписать (5) с возможностью пустых дефолтов (кроме, ясенпень, контрагента) - с их анализом и получением сводных значений по не указанным в параметре отборам. и получать по контрагенту сводный если надо.
прим.: только для скорости нужно иметь ввиду тот факт, что индекс регистра строится в порядке следования измерений, и если в вызове сводного остатка есть пропуск фильтров измерений (пустые значения а после них непустые) - вычисление сводного остатка сильно замедляется (т.к. вываливается в перебор а не по индексу), и для таких случаев может оказаться, что тупой перебор+подсуммировка по сводным остаткам по всем возможным значениям "пропущенного" измерения будет работать гораздо быстрее, чем разовое вычисление сводного остатка с таким пропуском (т.к. будут не перебором а по индексам).
33 AliAksA
 
30.08.18
14:35
ну может не так понял, но это шуршит за милую душу:

Перем БухИтоги;

Процедура ПриОткрытии()
    БухИтоги = СоздатьОбъект("БухгалтерскиеИтоги");
    БухИтоги.ПериодМ(ТекущаяДата());
КонецПроцедуры

Функция ТекущийДолг(перКонтрагент)
    Если ПустоеЗначение(перКонтрагент) = 0 Тогда
        Если перКонтрагент.ЭтоГруппа() = 0 Тогда
            Возврат Формат(БухИтоги.СКД(СчетПоКоду("62"), "С" , , перКонтрагент), "Ч018.2.'");
        КонецЕсли;
    КонецЕсли;
    Возврат "";
КонецФункции
Закон Брукера: Даже маленькая практика стоит большой теории.