Имя: Пароль:
1C
 
Правила обмена в 1С
,
0 busy1
 
16.02.15
15:44
Добрый день. Не когда не работал с правилами обмена и вот тут возникла необходимость. Необходимо подправить правила обмена так, что бы табличная часть документы с Номенклатурой, свернулась до нескольких специально заданных номенклатур. К примеру, в Ном.-1, Ном.-2, Ном.-3. Какая к какой категории относится указано в БД источника в Рег. св.
1 busy1
 
16.02.15
15:44
Не знаю даже куда копать
2 anatoly
 
16.02.15
15:48
бери КД и книжку по ней - и вперед!
3 busy1
 
16.02.15
15:50
КД взял, а можно как то направить какие главы книжки читать, что бы ускорить процесс.
4 busy1
 
16.02.15
15:51
я так понимаю, просто в каком - то месте необходимо написать процедура с запросом в РС по номенклатуре и замена одну на другую.
5 anatoly
 
16.02.15
15:58
(3) если книжка бояркин/филатов - читай главу 6.
(4) наверное: правила выгрузки - перед обработкой.
6 busy1
 
16.02.15
16:09
(5) Спасибо
7 busy1
 
16.02.15
16:36
Я правильно понимаю мне необходимо понять какой обработчик нужно для этого использовать? Может быть кто то знает... ;)
8 mikecool
 
16.02.15
16:37
пко номенклатура
перед выгрузкой
заменяй значение на то, что тебе надо
9 anatoly
 
16.02.15
16:42
(8) я так понял ему несколько товаров из ТЧ надо в 1 позицию группировать, так что по идее ПКО того документа где эта ТЧ.
10 GreatOne
 
16.02.15
16:48
Имхо, лучше подправить ПКГС. Там можно крутить-вертеть запросом из табличной части документа как вздумается и все удобно выгрузить в КоллекцияОбъектов.
11 busy1
 
16.02.15
17:18
Да в (9) всё верно понял
12 GreatOne
 
16.02.15
17:21
(11) В правило конвертации групп свойств в ПередОбработкой ставишь что-нибудь схожее:

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



Поля запроса должны совпадать с полями ТЧ
13 GreatOne
 
16.02.15
17:22
ой, там Запрос.УстановитьПараметр("Ссылка", ИСТОЧНИК);
14 GreatOne
 
16.02.15
17:23
Или тот же самый запрос делаешь в ПКО объекта ПередВыгрузкой, выгружаешь полученную тз во ВходящиеДанные. А у ТЧ ставишь галку "Получить из входящих данных"
15 busy1
 
16.02.15
17:28
Вот прям огромное спасибо. А то темный лес у меня в голове.
16 busy1
 
16.02.15
17:33
Только мне не группировать надо, а заменить одну номенклатуру на другую. То есть, у меня есть в ТЧ док. Ном01, Ном02, Ном3, мне надо её сгруппировать в НоменХХ. Что на что меняется указано в Регистре свойств
17 busy1
 
16.02.15
17:35
Но в принципе всё понятно, смысл тот же
18 anatoly
 
16.02.15
17:47
(16) ну в (12) просто пример правила был, а как именно группировать - это только тебе известно ))
19 busy1
 
16.02.15
17:57
Поимею наглость и задам ещё один вопрос. Можно ли как то с помощью правил обмена, из одного исх. док. базы источника, сделать несколько входящих базы приемника.
20 anatoly
 
16.02.15
18:08
(19) можно.
ты имеешь ввиду - для каждого по 2-3 других, или в зависимоти от данных - либо один либо другой тип документа?
21 busy1
 
16.02.15
18:14
Один и тот же тип документы. Всё это одна задача. Я беру документ к примеру поступление товара, смотрю тч. Батарей, ножи, и ручки я меняю на один элемент канц. товары, а пылесосы и утюги меняю на другой элемент Бытовая техника, выгружаю это из базы источника, а базу приемник загружаю два поступления по отдельно по канц. товарам, отдельно по бытовой техники.
22 GreatOne
 
16.02.15
20:43
(21) тут главное понять, как КД работает. Например ПКО ПослеЗагрузки - это уже на стороне приемника отрабатывает. В этом обработчике тебе доступен готовый объект, выгруженный из приемника. Это у тебя ПТиУ со свернутой номенклатурой. Ты может проанализировать ТЧ, там же, на ходу, создать новые документы Док.СоздатьОбъект();. Я примерно так выгружал из КА документ "ОплатаПлатежнойКартой": на стороне приемника создавал бух операцию+док.расчетов с контрагентом+сф на аванс и все это из анализа одного документа. Чтобы не было возможных дублей, я бух операции присваивал UID документа ОплатаПлатежнойКартой, и если он находился в базе, то свой код пропускал. Делалось через Если Не ОбъектНайден Тогда...
23 GreatOne
 
16.02.15
20:48
Но лучше создать два правила для ПТиУ: ПТиУ_КанцТовары + ПТиУ_БытоваяТехника. А в ПКО при анализе табличной части ПередВыгрузкой использовать ВыгрузитьПоПравила();


Если БытовыеУслуги Тогда
ВыгрузитьПоПравилу(Источник,,,,"ПТиУ_БытоваяТехника");
ИначеЕсли КанцТовары Тогда
ВыгрузитьПоПравилу(Источник,,,,"ПТиУ_КанцТовары");
КонецЕсли;
24 busy1
 
17.02.15
11:19
В продолжение темы.
25 busy1
 
17.02.15
11:26
Я так понимаю, План такой:
1. Создаю правила выгрузки данных для документа ПТиУ, в обработчик "Перед выгрузкой" помещаю свой код.
Запрос = Новый Запрос;
Запрос.Текст =
"
|ВЫБРАТЬ
|    аОтделыНоменклатуры.Номенклатура,
|    аОтделыНоменклатуры.Отдел
|ИЗ
|    РегистрСведений.аОтделыНоменклатуры КАК аОтделыНоменклатуры
|ГДЕ
|    аОтделыНоменклатуры.Номенклатура = &Номен
|";

Запрос.УстановитьПараметр(Номен, Источник.Номенклатура);
Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
    Сообщить(Источник.Номенклатура);    
КонецЕсли;
26 busy1
 
17.02.15
11:26
что то мне кажется не фига не получится
27 GreatOne
 
17.02.15
11:27
У вас по ходу каша в голове. Читайте Бояркина.
Кстати ПВД <> ПКО
28 busy1
 
17.02.15
11:30
(27) Да. Я не сталкивался с Конвертацией и как то всё для меня это темный лес.
29 busy1
 
17.02.15
11:32
На стороне приемника у меня нет возможности производить замену номенклатуры. Это необходимо сделать на стороне отправителя. Поэтому мне кажется что это надо сделать ПВД.
30 GreatOne
 
17.02.15
11:34
(28) лучше подучить, иначе в слепую ничего не получится сделать.
(29) на стороне отправителя отрабатывают 3 обработчика. А на счет ПВД - это да, даже лучше будет. У бояркина на стр. 80 отличный пример, там заказы в ципкле выгружаются через ВыгрузитьПоПравилу(), думаю идеальный вариант будет.
31 busy1
 
17.02.15
11:36
(30) Вот спасибо. На счёт подучить это да. Но так как времени особо нет. Буду стараться совмещать теорию и практику. Пробовать, смотреть что получается, читать форум и Бояркина.
Спасибо ещё раз за информацию.
32 Stim
 
17.02.15
11:52
"На стороне приемника у меня нет возможности производить замену номенклатуры."
с чего это?
обыкновенно при загрузке переопределяете номенклатуру.

в самом доке так же при загрузке группируете ТЧ по номенклатуре
33 busy1
 
17.02.15
12:16
(32) Потому что замена номенклатуры в тч зависит от значения этой номенклатуры в РС. А Рег. сведения находится в базе источника. Поэтому у меня уже в выгрузке номенклатура должна уже быть обработана, заменена и сгруппирована.
34 Stim
 
17.02.15
12:33
(33) понял.
тогда изменяй при выгрузке, аналогично
35 busy1
 
17.02.15
15:38
С ПВД как то сложновато кажется. Сделал ПКО для документы ПТиУ в обработчике "Перед выгрузкой" написал код:


Запрос = Новый Запрос;
Запрос.Текст =
"
|ВЫБРАТЬ
|    аОтделыНоменклатуры.Номенклатура,
|    аОтделыНоменклатуры.Отдел
|ИЗ
|    РегистрСведений.аОтделыНоменклатуры КАК аОтделыНоменклатуры
|ГДЕ
|    аОтделыНоменклатуры.Номенклатура = &Номен
|";

Для Каждого СтрокаТовары ИЗ Источник.Товары Цикл
     Запрос.УстановитьПараметр(Номен, Источник.Номенклатура);
     Результат = Запрос.Выполнить();
    Если НЕ Результат.Пустой() Тогда
        Если Результат.Отдел = 1 Тогда
            СтрокаТовары.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000002");
        ИначеЕсли Результат.Отдел = 2 Тогда
            СтрокаТовары.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000003");
        Иначе
            СтрокаТовары.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000004");
        КонецЕсли;
    КонецЕсли;    
КонецЕсли;

При загрузки выдает ошибку:

Ошибка в обработчике события ПередЗагрузкойДанных (конвертация)
    Обработчик             =  ПередЗагрузкойДанных (конвертация)
    ОписаниеОшибки         =  Ошибка компиляции при вычислении выражения или выполнении фрагмента кода: {(32,64)}: Переменная не определена (УзелОбменаЗагрузкаДанных)
    ПозицияМодуля          =  Обработка.УниверсальныйОбменДаннымиXML.МодульОбъекта(11949)
    КодСообщения           =  22

Вообще правильно так сделать код в ПКО ?
36 GreatOne
 
17.02.15
15:45
Вот это лихо:
Для Каждого СтрокаТовары ИЗ Источник.Товары Цикл
     Запрос.УстановитьПараметр(Номен, Источник.Номенклатура);
     Результат = Запрос.Выполнить();

Один и тот же запрос выполнить более 1 раза не получится)
37 GreatOne
 
17.02.15
15:51
Может так:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    аОтделыНоменклатуры.Номенклатура,
|    аОтделыНоменклатуры.Отдел
|ИЗ
|    РегистрСведений.аОтделыНоменклатуры КАК аОтделыНоменклатуры
|ГДЕ
|    аОтделыНоменклатуры.Номенклатура = &Номен
|";

ТЗ = Запрос.Выполнить().Выгрузить();
НомРаз = Справочники.Номенклатура.НайтиПоКоду("000002");
НомДва = Справочники.Номенклатура.НайтиПоКоду("000003");
НомТри = Справочники.Номенклатура.НайтиПоКоду("000004");
Для Каждого СтрокаТовары ИЗ ТЗ Цикл
    
        Если СтрокаТовары.Отдел = 1 Тогда
            СтрокаТовары.Номенклатура = НомРаз;
        ИначеЕсли Результат.Отдел = 2 Тогда
            СтрокаТовары.Номенклатура = НомДва;
        Иначе
            СтрокаТовары.Номенклатура = НомТри;
        КонецЕсли;
    КонецЕсли;    
КонецЕсли;

ВходящиеДанные = Новый Структура("Товары");
ВходящиеДанные.Товары = ТЗ;


А у ТЧ "Товары" поставить флаг "получить из входящих данных". Только в запрос поставь все остальные поля для ТЧ.
38 busy1
 
17.02.15
15:56
То есть я правильно понял, даже если я пишу в обработчике ПКО то все равно в ТЧ ставлю флаг "Получать из входящих данных". Я  ошибочно полагал, что данный флаг нужен если данные приходят из ПВД.
39 GreatOne
 
17.02.15
16:01
(38) и из ПВД тоже. Входящие данные можно из нескольких мест получать.
Из справки КД:
Данные передаются по следующим правилам:

1.      ПВД.ИсходящиеДанные -> ПКО.ВходящиеДанные

2.      ПКО.ВходящиеДанные -> ПКС.ВходящиеДанные

3.      ПКС.ИсходящиеДанные -> ПКО.ВходящиеДанные
40 GreatOne
 
17.02.15
16:02
у нас как раз второй вариант, так что используем входящие данные и в ПередВыгрузкой и для ПКГС(галка получать из входящих данных)
41 GreatOne
 
17.02.15
16:03
В ПВД тоже самое можно сделать, но понадобится заменить на ИсходящиеДанные= Новый Структура("Товары");
ИсходящиеДанные.Товары = ТЗ;
42 busy1
 
17.02.15
16:05
GreatOne я премного благодарен за консультацию, Вы мне здорово помогаете. Я ваш должник. Мой email [email protected] будете в Волгограде пишите.
Вот ещё в вашем примере немного не понятно, где устанавливается параметр номен в запросе.
или в каком виде попадает номенклатура.
43 GreatOne
 
17.02.15
16:10
(42) Нигде, я про него забыл)) В моем примере не надо отбор по номенклатуре делать, только отбор по самому документу. Мы же всю ТЧ перебирем в полученной ТЗ и ее же загрузим в новый документ. Так что там
|ГДЕ
|    аОтделыНоменклатуры.Регистратор = &НашДокумент
Как-то так.
Как буду в Волгограде - напишу)))

Вообще суть с КД уже ясна, остается только алгоритм замены/подстановки/сортировки/группировки или что там у вас придумать.
44 busy1
 
17.02.15
16:19
Суть КД ясна. Не могли бы Вы мне немного прояснить ситуацию. В книге я что то так и не понял. ТЧ нашего документа содержит разную номенклатуру из справочника, в запросе мы всего получаем номер отдела номенклатуры. И в дальнейшем исходя из номера меняем в ТЧ одну номенклатуру на одну из трёх. Регистратор в РС отделы номенклатуры не используется.
45 busy1
 
17.02.15
16:20
Не понятно, в каком виде поступает информация в ПКО. Я так понимаю в ПКО в перем Источник поступает один документ ПТиУ.
46 GreatOne
 
17.02.15
16:24
да уже от темы далеко ушли. Лучше заново сказать, что берем и что хотим получить. Я вот не пойму откуда тут РС вообще взялся. Кто источник? Кто приемник?

Если источник и приемник одинаковые, а данные по отделам номенклатуры лежат в РС, то можно ведь запросом взять номенклатуру из Приемника, левым соединением прикрепить отделы для номенклатуры и далее уже делать похожий цикл, как написано выше.
47 busy1
 
17.02.15
16:28
Источник УТ 11 приемник Бух. РС Отделы номенклатуры это какой то самостоятельный регистр в УТ в котором есть информация какая номенклатура относится к какому отделу.
48 Stim
 
17.02.15
16:33
на пустом месте развел непонятно что.
хочешь сделать правильно - создавай ПКГС к ТЧ Товары, в которой передОбработкой заполняй ТЧ КоллекцияОбъектов своими номенклатурами из РС
49 busy1
 
17.02.15
18:35
(48) Мне не надо заполнять номенклатурой из РС. в РС мне нужно посмотреть только к какой категории относится номенклатура из ТЧ. Что бы потом заменить номенклатур в ТЧ на другую номенклатуру. Всё.
50 Stim
 
18.02.15
09:23
(49) ну значит, передавай категорию в параметрах
51 Рэйв
 
18.02.15
09:41
(49)Проще всего в ПослеЗагрузки. Это как раз перед записью объекта в приемнике
Переберай у Объект таб. часть и заменяй по своим условиям.
52 Stim
 
18.02.15
09:50
(51) у него категория хранится в источнике
53 ultrannge89
 
18.02.15
10:18
А переработать структуру баз ни как? Чтобы меньше работы надо было делать в КД. Можно например в БУХ добавить реквизит в спр номенклатура (категория или отдел) и ее заполнять после выгрузки из УТ. А потом что угодно можно с этими данными делать, внешними обработками...
54 Stim
 
18.02.15
10:27
(53) чувак..
вместо того, чтобы сделать нормальное решение, ты предлагаешь мегакостыль.

конешн, вместо того, чтобы написать нормальные правила, давай добавим 20 реквизитов в ТЧ для хранения промежуточных значений, и 20 внешних обработок по их обработке. Самому не смешно?
55 Stim
 
18.02.15
10:28
+ я всегда говорил - лучше потратить пару дней и сделать нормальное решение,которое будет работать самостоятельно,
чем сделать костыль на скорую руку и тратить на его поддержание время постоянно
56 busy1
 
18.02.15
10:34
Доброе утро. Объясните жирафу, в справке к обработчикам написано "источник - выгружаемый объект". Если я создаю ПКГС к табличной части, то "источником" что будет является и как к нему можно будет обращаться. Если "источник" - это табличная часть то правильной ли будет запись. Источник.Номенклатура = ПеременнаяНоменклатуры; ?
57 busy1
 
18.02.15
10:35
(53) Нет так делать категорически нельзя. Полностью согласен с мнением Stim
58 Stim
 
18.02.15
10:37
(56)
Источник.Ссылка - твой док
КоллекцияОбъектов - выгружаемая ТЧ.
59 Stim
 
18.02.15
10:42
+ пишешь что-то типа в пкгс при выгрузке:
КоллекцияОбъектов = Источник.Ссылка.МояТЧ.Выгрузить();
КоллекцияОбъектов.колонки.Добавить("Категория")
Для каждого строкаКоллекции из КоллекцияОбъектов  цикл
СтрокаКоллекции.Категория = МояКатегория;
КонецЦикла;

естественно, добавляешь  поле Категория в ПКО(как параметр) своей ТЧ.

После загрузки номенлатуры пишешь что-то типа:

Значение = ПолучитьНоменклатуруПоКатегорииНоменклатуры(объектКоллекции.Номенклатура,объектКоллекции.Категория)
60 busy1
 
18.02.15
10:43
(58) То есть, обращаться к коллекции объектов я могу примерно так. КоллекцияОбъектов.Номенклатура = ПеременнаяНоменклатуры; ?
61 busy1
 
18.02.15
10:44
(59) Вот это наверное то, что надо!
62 busy1
 
18.02.15
10:44
Там случайно не где не надо ставить галочки "получать данные из внешних источников"?
63 Stim
 
18.02.15
10:46
(61) следи, чтобы колонки в КоллекцияОбъектов соответствовали составу пкгс. если у тебя конвертируются только 3 объекта табличной части, то и в КоллекцииОбъектов должно быть 3 колонки
64 Stim
 
18.02.15
10:46
(62) нет, просто оставляй источник пкгс незаполненным
65 Stim
 
18.02.15
10:47
галочка - для загрузки через произвольный запрос в пвд
66 busy1
 
18.02.15
10:56
Stim спасибо, буду грызть.
67 busy1
 
18.02.15
13:57
Запрос = Новый Запрос;
    Запрос.Текст =
    "
    |ВЫБРАТЬ
    |    аОтделыНоменклатуры.Номенклатура.Код КАК КодНом,
    |    аОтделыНоменклатуры.Отдел КАК КатегорияНом
    |ИЗ
    |    РегистрСведений.аОтделыНоменклатуры КАК аОтделыНоменклатуры
    |";
    
    РезультатЗапроса = Запрос.Выполнить.Выгрузить();
    
    элементСпрНом1 = Справочники.Номенклатура.НайтиПоКоду("000002");
    элементСпрНом2 = Справочники.Номенклатура.НайтиПоКоду("000003");
    элементСпрНом3 = Справочники.Номенклатура.НайтиПоКоду("000004");
    
    КоллекцияОбъектов = Источник.Ссылка.Товары.Выгрузить();
    Для каждого СтрокаКоллекции ИЗ КоллекцияОбъектов Цикл
        перемКодНомен = РезультатЗапроса.Найти(СтрокаКоллекции.Код, "КодНом");
        перемКодНомен = РезультатЗапроса.Найти(СтрокаКоллекции.Родитель.Код, "КодНом");
        Если перемКодНомен <> Неопределено Тогда
            Если перемКодНомен.КодНом = 1 Тогда
                СтрокаКоллекции.Номенклатура = элементСпрНом1;
            ИначеЕсли перемКодНомен.КодНом = 2 Тогда
                СтрокаКоллекции.Номенклатура = элементСпрНом2;
            Иначе
                СтрокаКоллекции.Номенклатура = элементСпрНом3;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
68 busy1
 
18.02.15
13:59
Вот сделал такой вот обработчик.
...

    ОписаниеОшибки         =  Поле объекта не обнаружено (Выполнить)
    ПозицияМодуля          =  ВнешняяОбработка.ОтладкаПравилОбмена.МодульОбъекта(149)
    КодСообщения           =  48
69 busy1
 
18.02.15
13:59
Вероятно запрос нельзя выполнить в принципе
70 Stim
 
18.02.15
14:12
(69) запрос нельзя выполнить.
его можно только Выполнить()
71 busy1
 
18.02.15
14:13
(70) Выгрузить Нельзя
72 Stim
 
18.02.15
14:16
(71) у тебя ошибка с выполнить
73 Stim
 
18.02.15
14:16
кароч, разбирайся дальше сам, наводку я тебе дал.
запускай отладчик при выгрузке и вперед
74 busy1
 
18.02.15
14:17
ааа. Семён Семеныч
75 busy1
 
18.02.15
14:17
выполнить блин со скобками.
Пользователь не знает, чего он хочет, пока не увидит то, что он получил. Эдвард Йодан