Имя: Пароль:
1C
1С v8
запрос по данным из файла формата дбф не находит номенклатуру
,
0 Grinpic
 
20.08.15
12:58
Доброго времени суток,
При выполнении в 1С 8.3, запрос по данным из файла формата дбф не находит номенклатуру, хотя она имеется в базе 1С, я ищу по 3 параметрам (Цена, количество, Наименование)
    
Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслуг.Товары.Номенклатура.Наименование
                          |ИЗ
                          |    Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
                          |ГДЕ
                          |    ПоступлениеТоваровУслуг.Товары.Цена = &Цена
                          |    И ПоступлениеТоваровУслуг.Товары.Количество = &Количество
                          |    И ПоступлениеТоваровУслуг.Товары.Номенклатура.Наименование = &Наименование");
    Запрос.УстановитьПараметр("Цена", Цен);
    Запрос.УстановитьПараметр("Количество", Кол);
    Запрос.УстановитьПараметр("Наименование", Номен);

    Результат=Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат Неопределено;
    КонецЕсли;


Также я не совсем понимаю для чего нужна выборка:    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();

Но в другом запросе она используется.. пример:
Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслуг.Ссылка
                          |ИЗ
                          |    Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
                          |ГДЕ
                          |    ПоступлениеТоваровУслуг.НомерВходящегоДокумента = &НомерКонтрагента
                          |    И ПоступлениеТоваровУслуг.Контрагент = &Контрагент
                          |    И ПоступлениеТоваровУслуг.Дата МЕЖДУ &ДатаН И &ДатаК");
    Запрос.УстановитьПараметр("НомерКонтрагента", НВход);
    Запрос.УстановитьПараметр("Контрагент", ПоискС(ИНН));
    Запрос.УстановитьПараметр("ДатаН", НачалоДня(НВДат));
    Запрос.УстановитьПараметр("ДатаК", КонецДня(НВДат));
    Результат=Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    
    Возврат Выборка.Ссылка;
Прощу вашей помощи!
1 ДенисЧ
 
20.08.15
13:00
занчит, одно из трёх - не совпадает.
2 Grinpic
 
20.08.15
13:01
(1) Все данные берутся с одной строчки из дбф, должно совпадать... Но проверю
3 okmail
 
20.08.15
13:01
Может быть пробелы лишние в начале/в конце.
4 Grinpic
 
20.08.15
13:04
(3) Нет пробелы убираю при получении из дбф информации Номен = (СокрЛП(База.ПолучитьЗначениеПоля("Nomen")));
5 el-gamberro
 
20.08.15
13:06
Тогда сделай наоборот, поиск с пробелами

"И ПоступлениеТоваровУслуг.Товары.Номенклатура.Наименование ПОДОБНО &Наименование"

Запрос.УстановитьПараметр("Наименование", "%"+Номен+"%");
6 salvator
 
20.08.15
13:06
(0) А че, самый первый запрос работает? И ошибку не выдает?
7 el-gamberro
 
20.08.15
13:07
Выборка.Следующий();
Возврат Выборка.Ссылка;

Возвращает самую первую строку запроса. Из нее берет первый попавшийся документ.
8 Grinpic
 
20.08.15
13:11
(6) Ошибок нет, потому что логикой предусмотрено, что должно вернуться тип "строка", иначе создается новый документ номенклатуры

    Если ТипЗнч(ПоискПостДок(ИНН, НВДат, НВход)) <> Тип("Строка") Тогда
        СоздатьДок(ИНН, Нном, НВход, НВДат, Ннаме, Номен, КНомен, ЕДИзм, Кол, Сумм, Цен, Итого);
        Сообщить("Документ создан");
    Иначе  
        Если ТипЗнч(ПоискПостДокНоменклатура( Номен, Кол, Цен)) <> Тип("Строка") Тогда
        ДобавитьНномПостВДок(Нном, Номен, ЕДИзм, Кол, Сумм,Цен, НВДат, ИНН, НВход);
        Сообщить("Работа с номенклатурой");
        Иначе
            Сообщить("Документ имеется в базе, номенклатура имеется в базе");
        КонецЕсли;
9 Grinpic
 
20.08.15
13:13
(7) но по идее там и должна быть одна строка, или это предусматривает что если будет несколько строк выберется первая?
10 el-gamberro
 
20.08.15
13:16
(9) Во первых надо что-то вернуть каким-либо образом. Во вторых может оказаться несколько документов за один день.
11 Grinpic
 
20.08.15
13:18
(10)     Запрос.УстановитьПараметр("ДатаН", НачалоДня(НВДат));
    Запрос.УстановитьПараметр("ДатаК", КонецДня(НВДат));
я данный документ ищу с точным временем и по 3 параметрам, все равно возможны совпадения?
12 Grinpic
 
20.08.15
13:20
(10) Ну в общем я понял, если тут главное выбор документа, + мы предусматриваем что их возможно будет несколько
13 1Сергей
 
20.08.15
13:21
(1) точно одно? :)
14 Grinpic
 
20.08.15
13:22
Возможно что то с форматом к примеру с дбф "Строка" приходит, а в 1С "Числовой", пойду проверю, данные также уже проверил совпадают
15 Grinpic
 
20.08.15
13:32
Теперь выдает ошибку что не смог найти "Наименование" - уже лучше))
16 Grinpic
 
20.08.15
13:49
Из ДБФ приходило формат "Строки" цена и количество, переделал на формат "Число", но теперь выходит ошибка:
{Форма.Форма.Форма(224)}: Поле объекта не обнаружено (Наименование)
    Возврат Выборка.Наименование;

При этом данные наименования сверил совпадают как тип так и сами данные, пробелов в базе 1С нет, поэтому и запрос без пробелов
17 1Сергей
 
20.08.15
13:54
(16)

Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслуг.Товары.Номенклатура.Наименование КАК Наименование
итд
18 Grinpic
 
20.08.15
13:58
(17) Прошу прощения, не могли бы расписать запрос полностью, я ищу по 3 параметрам, если вставить эту строку все валится...
19 el-gamberro
 
20.08.15
14:19
(18) Тебе нужно задать псевдоним в выборке, имя колонки если угодно :)

https://en.wikipedia.org/wiki/Aliasing_(computing)
20 el-gamberro
 
20.08.15
14:20
Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслуг.Товары.Номенклатура.Наименование КАК Наименование
                          |ИЗ
                          |    Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
                          |ГДЕ
                          |    ПоступлениеТоваровУслуг.Товары.Цена = &Цена
                          |    И ПоступлениеТоваровУслуг.Товары.Количество = &Количество
                          |    И ПоступлениеТоваровУслуг.Товары.Номенклатура.Наименование = &Наименование");
21 Grinpic
 
20.08.15
15:15
(20) Благодарю, проверю и сообщу!)
22 Grinpic
 
20.08.15
15:25
(20) Запрос не находит номенклатуру по какой то причине... из-за этогов документ добавляется новая таже самая...
23 el-gamberro
 
20.08.15
15:37
Используй не наименование, а ссылку на конкретную номенклатуру.
24 Grinpic
 
21.08.15
08:42
(23) сам документ является ссылкой - ПоступлениеТоваровУслуг, а номенклатура в нем уже не ссылка, а как дополнение к документу в виде товара, моя цель найти этот товар, чтобы при загрузке данных этот товар повторно не создавался, если он уже имеется в документе.
25 hhhh
 
21.08.15
09:15
(24) номенклатура - это не дополнение, это ссылка. Можно наоборот сказать. Номенклатуры - это всё ссылки, а документ - это иак , дополнение какое-то.
26 PuhUfa
 
21.08.15
09:24
Почему у ТС в запросе:
КАК ПоступлениеТоваровУслугТовары
а выборка просто из: ПоступлениеТоваровУслуг
Ошибку же должно выдавать?
27 hhhh
 
21.08.15
09:30
(26) ТС не знаком с возможностями копипаста. Он запрос походу здесь вручную набирал.
28 Grinpic
 
21.08.15
09:43
(27) нет запрос я копировал и составил в конструкторе запросов, запрос рабочий единственное он не находит наименование
29 Grinpic
 
21.08.15
09:46
(26) В данный момент запрос выглядит так:
Функция ПоискПостДокНоменклатура( Номен, Кол, Цен)
Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслугТовары.Номенклатура.Наименование КАК Наименование
                          |ИЗ
                          |    Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
                          |ГДЕ
                          |    ПоступлениеТоваровУслугТовары.Цена = &Цена
                          |    И ПоступлениеТоваровУслугТовары.Количество = &Количество
                          |    И ПоступлениеТоваровУслугТовары.Номенклатура.Наименование = &Наименование");
    Запрос.УстановитьПараметр("Цена", Число(Цен));
    Запрос.УстановитьПараметр("Количество", Число(Кол));
    Запрос.УстановитьПараметр("Наименование", Номен);

    Результат=Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    //Выборка.Следующий();
    
    Возврат Выборка.Наименование;
    
КонецФункции
30 Grinpic
 
21.08.15
09:53
(27) Тогда мне надо вернуть ссылку вместо наименования?
ПоступлениеТоваровУслугТовары.Номенклатура.Ссылка
А дальше уже сделать выборку
  Выборка = Результат.Выбрать();
    Выборка.Следующий();

    
    Возврат Выборка.ссылка.наименование;
31 hhhh
 
21.08.15
09:54
(28) но зачем вообще нужно искать по наименованию? Это же очень ненадежно, человек при наборе символов может ошибиться, а наименования сейчас могут быть 100 или даже 200 символов. Как людям работать?
32 Grinpic
 
21.08.15
09:56
(31) но если они ошибутся создастся новая номенклатура, т.к. выгрузка идет из дбф, документы и справочники создаются по мере необходимости
33 hhhh
 
21.08.15
09:57
Возврат Выборка.ссылка;
34 hhhh
 
21.08.15
09:58
(32) а количество зачем ищете?
35 Grinpic
 
21.08.15
10:00
Этот запрос ищет по нескольким параметрам, чтоб осуществлялась проверка и в документ не добавлялась таже номенклатура с тем же количеством и той же ценой и тем же наименованием
36 hhhh
 
21.08.15
10:01
(32) вам надо номенклатуру искать в справочнике Номенклатура. Если ее там нет, то добавить. А в оступлениях уже идут ссылки на этот справочник.
37 hhhh
 
21.08.15
10:03
(35) в дбф могут легко быть одинаковые строчки, поэтому должна обязательно "добавляться та же номенклатура с тем же количеством и той же ценой". Если она в дбф 2 раза, то и в поступлении должна быть 2 раза.
38 Grinpic
 
21.08.15
10:05
(36) Функция ПоискМ(Номен)
    
    Номенклатура = Справочники.Номенклатура;
    НайденнаяСсылка = Номенклатура.НайтиПоНаименованию(Номен);
    Если НайденнаяСсылка <> Номенклатура.ПустаяСсылка() Тогда
           Возврат НайденнаяСсылка;
        
    Иначе Возврат НайденнаяСсылка;
    КонецЕсли;
    
КонецФункции
Это я использую при добавлении новой номенклатуры в документе
А вот процедура которая ее юзает:
Процедура ДобавитьНномПостВДок(Нном, Номен, ЕДИзм, Кол, Сумм, Цен, НВдат, ИНН, НВход)
        НайденПост = ПоискПостДок2(ИНН, НВдат, НВход);
        ОткрНайденПост = НайденПост.ПолучитьОбъект();
        Строка = ОткрНайденПост.Товары.Добавить();
        Строка.СчетУчета = ПланыСчетов.Хозрасчетный.ПокупныеИзделия;
        Если ПоискМ(Номен)<>Справочники.Номенклатура.ПустаяСсылка() Тогда
            Строка.Номенклатура = ПоискМ(Номен);
            Сообщить("Элемент номенклатуры имеется в базе");
        Иначе СтрокаНом = Справочники.Номенклатура.СоздатьЭлемент();
              СтрокаНом.Родитель = Справочники.Номенклатура.НайтиПоНаименованию("Новые элементы");
              СтрокаНом.Наименование = Номен;
            СтрокаНом.ЕдиницаИзмерения = Справочники.КлассификаторЕдиницИзмерения.НайтиПоНаименованию(ЕДИзм);
              СтрокаНом.Записать();
              Если Справочники.Номенклатура.НайтиПоНаименованию(Номен)<>Справочники.Номенклатура.ПустаяСсылка() Тогда
                  Сообщить("Новый элемент номенклатуры создался");
            Иначе Сообщить ("Ошибка элемент не создался");
            КонецЕсли;
        КонецЕсли;
        Строка.Количество = Кол;
        Строка.Цена = Цен;
        Строка.Сумма = Сумм;
        Строка.ЕдиницаИзмерения = ЕДИзм;
        Попытка
        ОткрНайденПост.Записать(РежимЗаписиДокумента.Проведение);
        Исключение
            Сообщить(НСтр("ru = 'Невозможно провести документ.';"
             + " en = 'Document needs reposting.'"));
        КонецПопытки;
39 Grinpic
 
21.08.15
10:06
(37) согласен, как тогда лучше сделать чтоб лишняя номенклатура не добавлялась в док...
40 hhhh
 
21.08.15
10:07
(39) она должна добавляться.
41 Grinpic
 
21.08.15
10:10
(40) я имею ввиду что мы один раз выгрузили данные, выгружаем второй раз чтоб обновить и загружается повторно вся таже самая номенклатура сверху в доки
42 hhhh
 
21.08.15
10:11
(41) так и надо.
43 hhhh
 
21.08.15
10:12
(41) вам нужно очистить документ полностью и повторно грузить.
44 Grinpic
 
21.08.15
10:12
(42) ясно)) ну тогда этот запрос который я писал и не нужен)
45 Grinpic
 
21.08.15
10:13
(43) Оу ясно, пойду думать как удалять номенклатуру из дока, сам еще даже не пробовал в ручную))
46 Grinpic
 
21.08.15
10:25
(43) довольно просто удалять в ручную, знач проблем с удалением быть не должно, надо написать цикл которые будет это делать...)
47 hhhh
 
21.08.15
10:28
используй волшебную команду Очистить().
48 Grinpic
 
21.08.15
10:52
Запрос:
Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслуг.Ссылка
                          |ИЗ
                          |    Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
                          |ГДЕ
                          |    ПоступлениеТоваровУслуг.НомерВходящегоДокумента = &НомерКонтрагента
                          |    И ПоступлениеТоваровУслуг.Контрагент = &Контрагент
                          |    И ПоступлениеТоваровУслуг.Дата МЕЖДУ &ДатаН И &ДатаК");
    Запрос.УстановитьПараметр("НомерКонтрагента", НВход);
    Запрос.УстановитьПараметр("Контрагент", ПоискС(ИНН));
    Запрос.УстановитьПараметр("ДатаН", НачалоДня(НВДат));
    Запрос.УстановитьПараметр("ДатаК", КонецДня(НВДат));
    Результат=Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    
    Возврат Выборка.Ссылка;
Пойдет если я перед получением данных из дбф вставлю это?
ПоискПостДок2(ИНН, НВДат, НВход).Товары.Очистить();
49 Grinpic
 
21.08.15
11:02
(47) хм не пойдет, у меня там цикл который принимает данные построчно из дбф и создает по ним документы, в цикл поставить очистку нельзя т.к. он будет чистить всегда, в начале нельзя т.к он еще не получил данные из дбф и не сможет найти документ который надо чистить,
ну и в конец нельзя т.к. он после создания всех доков почистит последний, единственное что в голову приходит это сделать туже процедуру получения данных ранее и очищать данные перед повторным получением из дбф файла данных...
50 hhhh
 
21.08.15
11:12
(49) ну когда находите документ, тут же чистите. Это же элементарно, Ватсон.
51 hhhh
 
21.08.15
11:13
(49) а, понял, вы его миллион раз ищете. На каждой строчке ДБФ?
52 Grinpic
 
21.08.15
11:19
(51) ну да, там набор строчек и 2 развития событий, если номер дока уже есть в базе тогда добавляется новая номенклатура если нет, то создается новый док
53 Grinpic
 
21.08.15
11:21
(51) в этой же процедуре с начала получаю данные, после если есть док чищу товары, после, опять получаю данные, ищу док если есть добавляю док или номенклатуру))
54 Grinpic
 
21.08.15
11:23
(51) Работает окнечно, но долговато с учетом что документов будет 5 и возможно информации будет много
55 hhhh
 
21.08.15
11:31
(54) ну, если документов меньше 20000, не парьтесь насчет долготы. Вот если ближе к миллиону, тогда да, надо оптимизировать.
56 Grinpic
 
21.08.15
13:04
(55) У меня не чистит документ от товаров, - использую
    Если ТипЗнч(ПоискПостДок(ИНН, НВДат, НВход)) = Тип("Строка") Тогда
        ПоискПостДок2(ИНН, НВдат, НВход).Товары.Очистить();

//ПоискПостДок2(ИНН, НВдат, НВход) этот док имеет тип ссылка
Пытался сделать что то типо:
НайденПост = ПоискПостДок2(ИНН, НВдат, НВход);
        ОткрНайденПост =    НайденПост.ПолучитьОбъект();
ОткрНайденПост.Товары.Очистить();
Тоже не работает...
57 Grinpic
 
21.08.15
13:28
Заменил запрос чтоб вернуть объект в виде табличной части, проблема с передачей данных:
&НаСервере
Функция ПоискПостДок2(ИНН, НВДат, НВход)
    Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ПоступлениеТоваровУслуг.Ссылка
                          |ИЗ
                          |    Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
                          |ГДЕ
                          |    ПоступлениеТоваровУслуг.НомерВходящегоДокумента = &НомерКонтрагента
                          |    И ПоступлениеТоваровУслуг.Контрагент = &Контрагент
                          |    И ПоступлениеТоваровУслуг.Дата МЕЖДУ &ДатаН И &ДатаК");
    Запрос.УстановитьПараметр("НомерКонтрагента", НВход);
    Запрос.УстановитьПараметр("Контрагент", ПоискС(ИНН));
    Запрос.УстановитьПараметр("ДатаН", НачалоДня(НВДат));
    Запрос.УстановитьПараметр("ДатаК", КонецДня(НВДат));
    Результат=Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    
    Возврат Выборка.Ссылка.ПолучитьОбъект().Товары;
    
КонецФункции

Моя процедуры принимает:
        НайденПост = ПоискПостДок2(ИНН, НВдат, НВход);
        НайденПост.Товары.Очистить();

Есть идеи, как сделать чтоб заработало?
58 Grinpic
 
21.08.15
14:13
Видать надо выбрать объекты, а после очищать.. попробую поискать побольше информации о функции Очистить()
59 hhhh
 
21.08.15
15:08
НайденПост = ПоискПостДок2(ИНН, НВдат, НВход);
        ОткрНайденПост =    НайденПост.ПолучитьОбъект();

ОткрНайденПост.Товары.Очистить();
ОткрНайденПост.Записать();
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс