Вход | Регистрация

1С:Предприятие ::

Метки: документы

Как разместить документ между двумя другими?..

Я
   Львенок
 
11.05.04 - 10:07
Вопрос такой. Опять таки по экзаменационному заданию... Есть документы "Чек" разбросанные в пределах дня. Есть документ "ПриходнаяНакладная" созданный программно на их основе, приходующий на склад все товары проданные в "Чеках", находящейся где-то в начале дня. Есть документы "Перемещение", созданные также программно на основе "Чеков" и "ПриходнойНакладной" которые перемещает товар со склада в отдел где он был продан "чеком". По логике работы программы, "Перемещение" использует данные из регистров остатков, для определения возможности переместить товар и рассчета себестоимости перемещаемого товара, т.е. должен находиться после "ПриходнойНакладной", но до "Чеков". Чеки к моменту создания "Перемещения" уже существуют, "ПриходнаяНакладная" тоже должна существовать, иначе не будет хватать товара для перемещения.
Как наиболее просто сделать так, чтобы вновь создаваемые программно(!) документы "Перемещение" были дружно записаны после последней "ПриходнойНакладной" текущего дня, но до первого "Чека" текущего дня?
Можно, конечно, извратиться (как я и сделал за незнанием другого варианта) определить время последней "ПриходнойНакладной" за сегодня, и для каждого перемещения прибавить к нему одну секунду (при необходимости увеличить минуты и часы) и воспользоваться Док.УстановитьВремя(Часы,Минуты,Секунды);
А проще-то можно?
___
Искренне Ваш, Львенок.
 
 
   Таня
 
1 - 11.05.04 - 11:09
Я также делала, но только у меня не 1 секунда прибавлялась а почему то сразу 10
   Bzzzzz
 
2 - 11.05.04 - 11:26
Это задание, где документы должны создаваться программно обработкой?
   Bzzzzz
 
3 - 11.05.04 - 11:27
Я использовал АвтоВремяНачалоДня()
   Таня
 
4 - 11.05.04 - 11:31
Начало дня подходит только для Приходной накладной
   Bzzzzz
 
5 - 11.05.04 - 11:36
Делаешь Запрос по регистру Продажи.
Создаешь документы Премещение (в начало дня).
Создаешь документы ПрихНакл ( в начало дня).
Программно проводишь все документы, в том числе и Чеки.
   Львенок
 
6 - 11.05.04 - 11:42
(4) Самое обидное то, что все "ПриходнаяНакладные" формируются ТОЛЬКО в первом числе месяца (по заданию), т.е. АвтоВремяНачалоДня() подходит для всех "Перемещений", кроме(!) перемещений самого этого первого числа (потому что только в нем есть документ "Приходная...", который должен быть еще раньше)! И вот из-за этого одного особого дня, собственно и весь #$&^#@!..
Впрочем, сейчас в качестве эксперимента я вывернул логику работы программы на изнанку... и у меня сначала создаются (но не проводятся) все "перемещения" в начале дня, потом "приходы" тоже в начале дня. При этом проблем со временем нет... А потом все по очереди проводится, а заодно и последовательность восстанавливается (что тоже есть в задании)... Но это по прежнему удаление гланд через ж... а хочется красиво и элегантно...
___
Искренне Ваш, Львенок.
   Gavrila
 
7 - 11.05.04 - 11:55
(6) "... а хочется красиво и элегантно... " - два года с этим боремся :)
   427
 
8 - 11.05.04 - 13:13
Охохохохо.... неверно построенный алгоритм формирования приходов задним числом ....
   Львенок
 
9 - 11.05.04 - 17:48
(9) Дык я и не утверждал, что мой алгоритм верен, я просто не вижу принципиально иных алгоритмов и делаю так, как умею. Кстати, не ясно чего неверного-то? Результаты получаются вроде именно те, которые я ожидал.
Подскажи (намекни, уточни, тыкни пальцем) что не так, и как надо правильно, буду более чем признателен.
___
Искренне Ваш, Львенок.
   Serg_bl
 
10 - 12.05.04 - 04:03
Как вариант, можно взять первый документ (который будет Приходная), второй (Чек), вычислить время первого и второго, и Перемещение вставить между ними.
Функция ПолучитьВремяДок(лДок) 
    Перем Ч,М,С;
    
    лДок.ПолучитьВремя(Ч,М,С);
    ВремяДок = С+М*60+Ч*3600;
    Возврат ВремяДок;
    
КонецФункции//ПолучитьВремя 

//--------------------------------------------------------
Процедура УстановитьВремяДок(лНужноеВремя,лНужныйДок)
    Перем Ч,М,С;
    
    ОстВрем = лНужноеВремя;
    Ч = ЦЕЛ(ОстВрем/3600);
    ОстВрем = ОстВрем - (Ч*3600);
    М = ЦЕЛ(ОстВрем/60);
    С = ОстВрем - (М*60);
    лНужныйДок.АвтоВремяОтключить();
    лНужныйДок.УстановитьВремя(Ч,М,С);
    
КонецПроцедуры
//--------------------------------------------------------

Процедура УстановитьВремяДокумента(ДокПер);
    
    лДатаДок = ДокПер.ДатаДок;
    Если лДатаДок <> НачМесяца(лДатаДок) Тогда
         ДокПер.АвтоВремяНачалоДня();
         Возврат;
    КонецЕсли;
   //если это первый день месяца, значит в начале дня есть приходные

   //получим последний док приходную и следующий за ним товарный чек,

   //а между ними запишем Перемещение

    
    ДокПрих = СоздатьОбъект("Документ.ПриходнаяНакладная");
    ДокПрих.ОбратныйПорядок(1);
    ДокПрих.ВыбратьДокументы();
    Пока ДокПрих.ПолучитьДокумент()=1 Цикл
        Если (ДокПрих.ПометкаУдаления()=1) ИЛИ (ДокПрих.Проведен()=0) Тогда
            Продолжить;
        КонецЕсли;
        ПоследнийДокПрих = ДокПрих.ТекущийДокумент();
        Прервать;
    КонецЦикла;
    
    ПозДок = СформироватьПозициюДокумента(ПоследнийДокПрих,1);
    ДокЧек = СоздатьОбъект("Документ");
    ДокЧек.ВыбратьДокументы(ПозДок,);
    Пока ДокЧек.ПолучитьДокумент()=1 Цикл
       //перемещение запишем перед любым товарным чеком

       //Если (ДокЧек.ПометкаУдаления()=1) ИЛИ (ДокЧек.Проведен()=0) Тогда

       //    Продолжить;

       //КонецЕсли; 

        
        ПервыйДокЧек = ДокЧек.ТекущийДокумент();
        Прервать;
    КонецЦикла;
   //получим время документов

    ВремяДокПрих = ПолучитьВремяДок(ПоследнийДокПрих);
    ВремяДокЧек  = ПолучитьВремяДок(ПервыйДокЧек);
   //запишем перемещение между ними

    ВремяДокПер = (ВремяДокПрих+ВремяДокЧек)/2;
    УстановитьВремяДок(ВремяДокПер,ДокПер);
    
    
КонецПроцедуры
//--------------------------------------------------------
 
  Рекламное место пустует
   Львенок
 
11 - 12.05.04 - 09:27
На самом деле в итоге у меня получился такой код (ничего _между_ не вставляется):
Процедура Выполнить()  
//    НачатьТранзакцию();

    Если (КонМесяца(ВыбДата)>ПолучитьДатуТА()) Тогда
        Сообщить ("Дата конца месяца больше даты ТА, рассчет будет произведен по дату ТА");
    КонецЕсли;
ДатаНач=НачМесяца(ВыбДата); ДатаКон=МИН(КонМесяца(ВыбДата),ПолучитьДатуТА());

//--------------Запрос-------------------------------------------------------------

    Сообщить ("Запрос к итогам...");    
    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса = 
    "//{{ЗАПРОС(Сформировать)

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

    Сообщить("Формируем перемещения...");
    Запрос.Выгрузить(ТаблИ,0,0);
    ТаблИ.Свернуть("День,Отдел,Товар","КоличествоСумма");
    ТаблИ.Сортировать("День+,Отдел+,Товар+");    

    Док=СоздатьОбъект("Документ.Перемещение");
    Док.ВыбратьДокументы(ДатаНач,ДатаКон);
    Пока Док.ПолучитьДокумент()=1 Цикл
        Док.Удалить()//Это либо устаревший документ, либо вообще непонятно какой.

    КонецЦикла;              
    Док.АвтоВремяНачалоДня();
    Строк=ТаблИ.КоличествоСтрок();К=1;
    Пока К<=Строк Цикл
        ТаблИ.ПолучитьСтрокуПоНомеру(К);
        День=ТаблИ.День;            
        Пока К<=Строк Цикл
            ТаблИ.ПолучитьСтрокуПоНомеру(К);
            Если (День<>ТаблИ.День) Тогда Прервать; КонецЕсли;
            Отдел=ТаблИ.Отдел; 
            Док.Новый();     
            Док.ДатаДок=День;
            Док.Откуда=Константа.Склад;
            Док.Куда=Отдел;
            Пока К<=Строк Цикл
                ТаблИ.ПолучитьСтрокуПоНомеру(К);
                Если (Отдел<>ТаблИ.Отдел) ИЛИ (День<>ТаблИ.День) Тогда Прервать; КонецЕсли;
                Док.НоваяСтрока();
                Док.Товар=ТаблИ.Товар;
                Док.Количество=ТаблИ.КоличествоСумма;         
                К=К+1;
            КонецЦикла;
            Док.Записать();
            СписДок.ДобавитьЗначение(Док.ТекущийДокумент());    
        КонецЦикла;
    КонецЦикла;
    
//----------------------Закупка------------------------------

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

    КонецЦикла;              
    Док.АвтоВремяНачалоДня();
    
    Строк=ТаблИ.КоличествоСтрок(); К=1;
    Пока К<=Строк Цикл
        ТаблИ.ПолучитьСтрокуПоНомеру(К);
        Поставщик=ТаблИ.Поставщик;
        Док.Новый();        
        Док.ДатаДок=ДатаНач;
        Док.Поставщик=Поставщик;
        Пока К<=Строк Цикл    
            ТаблИ.ПолучитьСтрокуПоНомеру(К);
            Если (Поставщик<>ТаблИ.Поставщик) Тогда Прервать; КонецЕсли;
            Док.НоваяСтрока();
            Док.Товар=ТаблИ.Товар;
            Док.Количество=ТаблИ.КоличествоСумма;
            Док.Стоимость=ТаблИ.СуммаСумма*(100-Поставщик.Процент)/100//Сумма - процент комисс вознагр

            Док.Цена=?(Док.Количество<>0,Док.Стоимость/Док.Количество,0);
            К=К+1;
        КонецЦикла;    
        Док.Записать();
        СписДок.ДобавитьЗначение(Док.ТекущийДокумент());
    КонецЦикла;
//ЗафиксироватьТранзакцию();

//--------------Последовательность    ------------------------------------------------
    Сообщить("Восстанавливаем последовательность...");
    Документ=СоздатьОбъект("Документ");
    
    Документ.ВыбратьДокументы(МИН(Последовательность.Продажи.ПолучитьПозицию(),ДатаНач),);
    Пока Документ.ПолучитьДокумент()>0 Цикл
        Если (Документ.Проведен()=1) ИЛИ (СписДок.НайтиЗначение(Документ.ТекущийДокумент())>0) Тогда
            Документ.Провести(0,1);
        КонецЕсли;
    КонецЦикла;  
КонецПроцедуры
   Nat
 
12 - 29.06.04 - 16:06
У меня вопрос по этому заданию: каким образом здесь учтен ПЕРИОДИЧЕСКИЙ реквизит "Процент комиссионного вознаграждения" - а именно на какую дату надо брать значение - на дату формирования накладной , на дату продажи или на конец месяца?


Список тем форума
Рекламное место пустует   Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует