Имя: Пароль:
1C
1С v8
v8: Вычисление средней по остаткам
0 JeyRico
 
02.12.11
11:00
Моя первая задача в 1С, поэтому решаю как могу :)
Платформа 8.2
Суть вопроса в следующем:
Нужно вычислить среднюю по остаткам.
В расходную накладную нужно вписать среднюю по остаткам цену
склад один, на нулевость пока не проверяю.
Есть регистр накопления ОстаткиТоваров
Создал Общий модуль с галочкой - сервер:
Код:
---------------------------------------------------------------------
Функция ТекущиеОстатки(Товар) Экспорт
   /// Вот тут запрашиваем данные из регистра остатков
   /// по данному товару
       ЗапросОстатков = Новый Запрос();
       ЗапросОстатков.Текст = "ВЫБРАТЬ
           |    Остатки.Количество, Остатки.Стоимость
           |ИЗ
           |   РегистрНакопления.ОстаткиТоваров КАК Остатки
           |Где
           |    Остатки.Товар = &Товар" ;
       ЗапросОстатков.УстановитьПараметр("Товар", Товар);
       Результат = ЗапросОстатков.Выполнить();
       Сообщить("Отработала ф-я ТекущиеОстатки(Товар)");
       Возврат Результат;
КонецФункции
---------------------------------------------------------------------
КонецКода





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

   конецПопытки    
КонецФункции
----------------------------------------------------------------------------------
КонецКода


Есть модуль формы РасходнаяНакладная
Код:
----------------------------------------------------------------------------------
&НаКлиенте
Процедура МатериалыТоварПриИзменении(Элемент)
   ТекущаяСтрока = Элементы.Материалы.ТекущиеДанные;
   //ТекущаяСтрока.Цена = АвтоРасчетТаблиц.СредняяЦена(ТекущаяСтрока.Товар);
   Сообщить(АвтоРасчетТаблиц.СредняяЦена(ТекущаяСтрока.Товар));
   
   //Сообщить("Цене присвоено значение = " + ТекущаяСтрока.Цена);
КонецПроцедуры
----------------------------------------------------------------------------------
КонецКода

В итоге в цене в расходной накладной оказывается ноль, хотя остатки ненулевые и стоимость тоже
Может надо по другому получать среднюю?
1 Maxus43
 
02.12.11
11:03
Выборка.Получить(0) - вобще не кошерно так перебирать
2 Maxus43
 
02.12.11
11:05
Выборка.Получить(1) / Выборка.Получить(0);

это вобще чудо формула.
Переделывай всё номрально
3 Reset
 
02.12.11
11:09
(2) Он делит стоимость на количество так. Запись ужасна, разумеется, но ошибка не в этом
4 Domanoff26
 
02.12.11
11:12
Сообщить(Выборка.Получить(0));
Сообщить(Выборка.Получить(1));
что тут сообщает?
5 Domanoff26
 
02.12.11
11:14
(1) за то смотри какие кошерные прибамбасы
Код:
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
КонецКода
6 Maxus43
 
02.12.11
11:16
(5) да, это меняет всю ситуацию)
7 JeyRico
 
02.12.11
11:28
(4) туда вообще не доходит
при отладке останавливается на строке

Выборка = ТекущиеОстатки.Выбрать();
в модуле
функция СредняяЦена(Товар) экспорт
и снова выбрасывает в форму РасходнойНакладной

(2) Рад бы, а как нормально?
8 Maxus43
 
02.12.11
11:33
если Выборка.Следующий()
           тогда
Сообщить(Выборка.Количество)
Сообщить(ВыборкаСтоимость)
Иначе
Сообщить("по нулям всё")
КонецЕсли
9 mikecool
 
02.12.11
11:41
расскажите - что такое средняя по остаткам цена?
10 Maxus43
 
02.12.11
11:41
(9) отгадай)
11 mikecool
 
02.12.11
11:42
(10) не хочу гадать, хочу знать )))
12 JeyRico
 
02.12.11
11:50
(9)
Принимаем один и тот же товар:
1. Приходная накладная  10 шт по 10 рублей
2. Приходная накладная  20 шт по 15 рублей

Списываем:
Средняя по остаткам (10шт*10р + 20шт*15р)/ (10шт+20шт) = 13,33р
13 JeyRico
 
02.12.11
11:57
(8) В ТекущихОстатках значение
неопределено
Сообщить("Отработала ф-я ТекущиеОстатки(Товар)");
и вот этого сообщения не приходит
14 Maxus43
 
02.12.11
12:07
(13) это сообщить у тебя на сервере выполняется, кому сообщать то?
15 Maxus43
 
02.12.11
12:12
смотри что где доступно. на сервере Выборка доступна, а вот на клиенте вроде нет. Возвращать с сервера надо уже средню цену ибо примитивный числовой тип точно передаётся
16 JeyRico
 
02.12.11
12:19
Процедура ОбработкаПроведения(Отказ, Режим)
   //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
   // Данный фрагмент построен конструктором.
   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

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

   //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
   // регистр ОстаткиНаПериод
   // Сюда заносим текущие остатки, чтобы можно было получить
   // Количество товаров и их стоимость за любой период
   Движения.ОстаткиНаПериод.Записывать = Истина;
   
   Для Каждого ТекСтрокаМатериалы Из Материалы Цикл
       Движение = Движения.ОстаткиНаПериод.Добавить();
       Движение.Период = Дата;
       Движение.Товар = ТекСтрокаМатериалы.Товар;
       Движение.Склад = Склад;
       // Вызываем функцию из общего модуля с параметром Товар
       // Функция вернет Результат запроса
       ТекущиеОстатки = ПолучитьИзРегистра.ТекущиеОстатки(ТекСтрокаМатериалы.Товар);
       // Сохраняем полученный рузультат в регистре сведений
       Выборка = ТекущиеОстатки.Выбрать();
       Если Выборка.Следующий() <> Неопределено тогда
           Сообщить("Занесено в регистр -" + Выборка.Получить(0));
           Движение.Количество = Выборка.Получить(0); //Количество товара в остатках
           Движение.Стоимость = Выборка.Получить(1);  //Его стоимость
         КонецЕсли;
       
   КонецЦикла;
   
КонецПроцедуры


Процедура проведения работает и сообщает и заносит
17 JeyRico
 
02.12.11
12:22
Процедура проведения (16) работает и сообщает и заносит,
а вот процедура расчет средней цены что-то тупит.
18 JeyRico
 
02.12.11
12:22
Вернее я что-то туплю
19 Maxus43
 
02.12.11
12:22
(16) разберись что где выполняется Сервер/Клиент, поймёш сразу
20 JeyRico
 
02.12.11
12:26
Если правильно понял, то мне для СредняяЦена нужно директиву &НаСервере поставить? Ща попробую
21 JeyRico
 
02.12.11
12:31
{Документ.РасходнаяНакладная.Форма.ФормаДокумента.Форма(21)}: Метод объекта не обнаружен (СредняяЦена)
   Сообщить(АвтоРасчетТаблиц.СредняяЦена(ТекущаяСтрока.Товар));
22 JeyRico
 
02.12.11
12:41
Ура! Заработало.
(19) Спасибо, именно это и помогло. Не вижу кармы - плюсануть бы...
Вообщем функцию СредняяЦена загнал в модуль ПолучитьИзРегистра
Аминь.
23 URAL
 
02.12.11
13:19
А в запросе не устраивает среднюю получить?
24 JeyRico
 
02.12.11
13:30
(23) Мне из него потом еще максимальное количество выковыривать
25 Я не курил
 
02.12.11
13:34
(24) одно другому не мешает
26 JeyRico
 
02.12.11
14:20
Что-то запрос мне не нравиться, он мне возвращает количество и цену как в последнем проведенном документе, а надо чтобы просуммированное количество и сумму.
Как исправить?
27 DrHiHi
 
02.12.11
14:25
|    Остатки.Количество, Остатки.Стоимость
           |ИЗ
           |   РегистрНакопления.ОстаткиТоваров КАК Остатки
           |Где
           |    Остатки.Товар = &Товар" ;
че за чудо??
тебе ведь нужны остатки?? то использую таблица остатков "РегистрНакопления.ОстаткиТоваров.Остатки(, Товар = &Товар)"
28 JeyRico
 
02.12.11
14:36
Так должно быть?
ЗапросОстатков = Новый Запрос();
       ЗапросОстатков.Текст = "ВЫБРАТЬ
           |    Остатки.Количество, Остатки.Стоимость
           |ИЗ
           |   РегистрНакопления.ОстаткиТоваров КАК Остатки
           |Где
           |    РегистрНакопления.ОстаткиТоваров.Остатки(, Товар = &Товар)" ;
       ЗапросОстатков.УстановитьПараметр("Товар", Товар);
       Результат = ЗапросОстатков.Выполнить();
       Сообщить("Отработала ф-я ТекущиеОстатки(Товар)");
       Возврат Результат;
29 DrHiHi
 
02.12.11
14:41
(28) нет вместо "РегистрНакопления.ОстаткиТоваров" используй РегистрНакопления.ОстаткиТоваров.Остатки(, Товар = &Товар)

И что у тебя такое Стоимость?? это сумма или это цена?? если цена то скорее всего налажал в регистре и там должна быть сумма остатков, а стоимость уже вычесляешь сумма / количество, только еще количество проверь на 0
30 DrHiHi
 
02.12.11
14:42
конструктором запроса пользуйся
31 JeyRico
 
02.12.11
14:58
В стоимости сумма записывается
32 JeyRico
 
02.12.11
15:31
Выбрасывает исключение


попытка
       ЗапросОстатков = Новый Запрос();
       ЗапросОстатков.Текст = "ВЫБРАТЬ
           |    Остатки.Количество, Остатки.Стоимость
           |ИЗ
           |   РегистрНакопления.ОстаткиТоваров.Остатки(, Товар = &Товар) КАК Остатки" ;
       ЗапросОстатков.УстановитьПараметр("Товар", Товар);
       Результат = ЗапросОстатков.Выполнить();
       А=1;
       Возврат Результат;
   исключение
       сообщить("ошибка");
   конецПопытки;
33 JeyRico
 
02.12.11
15:34
(30) не нашел :(
34 URAL
 
02.12.11
15:36
(31) определись с полями изначально, что извлекаешь? называться могут как угодно, это не показатель

опиши поля регистра, посмотри когда документ производит запись в регистр какие поля заполняет, вот исходя из этого потом формируй запрос
35 JeyRico
 
02.12.11
15:47
(31) был ответом на (28)
36 JeyRico
 
02.12.11
15:47
Вернее (31) был ответом на (29)
37 hhhh
 
02.12.11
16:01
(36) вообще-то поля там

        |    Остатки.КоличествоОстаток, Остатки.СтоимостьОстаток


может, забить на эту 1С? Тем более пятница.
38 URAL
 
02.12.11
16:17
(37)думаю он смотрит в документе, там может это сумма, а в регистре стоимость )))
39 URAL
 
02.12.11
16:18
(35) и (36) смотри (38)
40 JeyRico
 
02.12.11
16:26
(37) Спасибо, это помогло справиться с исключением (запрос исправил)
еще вот это помогло :)
v8: выбрать остатки товара на складе
Теперь на выходе не РезультатЗапроса, а ТаблицаЗначений - 2 функции переделывать, т.к. Выборка здесь не катит...
41 JeyRico
 
02.12.11
16:38
Ничего не понимаю
На выходе получаю результат запроса.
А выбрать() дает исключение.
42 JeyRico
 
02.12.11
16:43
В КоличествоОстаток и СтоимостьОстаток пишеть ошибка чтения значения