Имя: Пароль:
1C
 
Работа с доп.реквизитами
↓ (Волшебник 21.12.2023 22:31)
0 stajer666
 
21.12.23
10:49
В общем, задача следующая:
Есть эксель файлик, который открывается, далее идет его обработка и запись в справочник, на этом моменте должна быть проверка элементов на уникальность, в табличке эксель она задается инв. номером, в конфигурации такого реквизита нет, потому добавил доп. реквизит

Проблема в следующем - не получается обратиться к значению доп. реквизита, чтобы сравнить с ним инв. номер из таблички эксель, также и не получается записать в него)) Ну просто никак не выходит рабочий код, даже показывать что-то из моих потугов стыдно

Такие вот задачки дают стажерам, отработавшим 3 дня))
1 Волшебник
 
21.12.23
10:54
Не стыдитесь. Покажите программный код
2 stajer666
 
21.12.23
11:00
СвойствоИдентификатора = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "ИнвНомераИзФайлаExcel");
"ВЫБРАТЬ
         |    ОсновныеСредстваДополнительныеРеквизиты.Ссылка КАК Ссылка,
         |    ОсновныеСредстваДополнительныеРеквизиты.Свойство КАК Свойство,
         |    ОсновныеСредстваДополнительныеРеквизиты.Значение КАК Значение
         |ИЗ
         |    Справочник.ОсновныеСредства.ДополнительныеРеквизиты КАК ОсновныеСредстваДополнительныеРеквизиты
         |ГДЕ
         |    ОсновныеСредстваДополнительныеРеквизиты.Ссылка = &Ссылка
         |    И ОсновныеСредстваДополнительныеРеквизиты.Свойство = &ИнвНомераИзФайлаExcel";
        
    
        
    Запрос.УстановитьПараметр("Свойство", СвойствоИдентификатора);
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    
    РезультатЗапроса = Запрос.Выполнить();
    
       ВыборкаДетальныеЗаписи = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    СсылкаНаОС = Справочники.ОсновныеСредства.ПустаяСсылка();
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        
    КонецЦикла;
    
    
    
    Если НЕ ЗначениеЗаполнено(СсылкаНаОС) Тогда
        ОС = Справочники.ОсновныеСредства.СоздатьЭлемент();
    Иначе
        ОС = СсылкаНаОС.ПолучитьОбъект();
    КонецЕсли;
    
    СтруктураОтбора = Новый Структура("Свойство", СвойствоИдентификатора);
    
    НайденныеСтроки = ОС.ДополнительныеРеквизиты.НайтиСтроки(СтруктураОтбора);
    Если НайденныеСтроки.Количество() > 0 Тогда
        СтрокаДляРедактирования = ОС.ДополнительныеРеквизиты.Добавить();
    КонецЕсли;
    
    СтрокаДляРедактирования.Свойство = СвойствоИдентификатора;
    СтрокаДляРедактирования.Значение = "123";    

Начальник накидал такой код для примера, дергать его по каждому пункту, понятное дело, я не могу

в конце "123" - строка с инв.номером, которую я вытяну из файла эксель

непонятно следующее: что вообще такое Ссылка, что туда вставлять, да и как оно работает в принципе тоже не понимаю
3 Волшебник
 
21.12.23
11:01
здесь пустой цикл

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
КонецЦикла;
4 stajer666
 
21.12.23
11:02
Мне нужно как-то сравнивать мой инв.номер из файла эксель со всеми значениями доп.реквизита в справочнике, если такого не найдется, создавать новый элемент и вписывать в него инв. номер в доп.реквизит
5 stajer666
 
21.12.23
11:05
(3) честно, я без малейших идей, что он должен делать, пытался донести до начальника, что в запросах я вообще не ку-ку, буквально ни одного не создал за свое время обучения, но он все равно дал мне его
6 Волшебник
 
21.12.23
11:05
Здесь ошибки:

|ГДЕ
         |    ОсновныеСредстваДополнительныеРеквизиты.Ссылка = &Ссылка
         |    И ОсновныеСредстваДополнительныеРеквизиты.Свойство = &ИнвНомераИзФайлаExcel";
        
          
    Запрос.УстановитьПараметр("Свойство", СвойствоИдентификатора);
    Запрос.УстановитьПараметр("Ссылка", Ссылка);

Правильнее так:

|ГДЕ
         |    ОсновныеСредстваДополнительныеРеквизиты.Ссылка = &Ссылка
         |    И ОсновныеСредстваДополнительныеРеквизиты.Свойство = &Свойство
         |    И ОсновныеСредстваДополнительныеРеквизиты.Значение = &ИнвНомераИзФайлаExcel";
7 Волшебник
 
21.12.23
11:05
(5) Вас надо уволить с позором
8 Смотрящий
 
21.12.23
11:09
(3) Он в тебя верит. Даже если ты не веришь в Него. ))
9 stajer666
 
21.12.23
11:10
(7) ну, тут так и не скажи, для меня, как для стажера, задачка кажется довольно непростой

это ж сначала надо написать часть с открытием файла эксель, потом его запись в справочник, а после создание документа

да и везде куча нюансов с отбором по строками, колонками, занесением части колонок в комментарии и тд
10 stajer666
 
21.12.23
11:11
(9) к тому же это все реализуется не одной кнопкой, а двумя, одна записывает Основные средства с определенной строки, другая ТМЦ, с ТМЦ проблем не возникло, так как там у всех элементов уникальные наименования, а с ОС приходится возиться
11 stajer666
 
21.12.23
11:12
(6) эту част подправил, пустой цикл закомментировал, но догадок, что делать дальше, у меня нет))

может, можно как-то проще реализовать через БСП? там тоже пытался повозиться некоторое время, но пришел к тому же результату
12 shuhard
 
21.12.23
11:14
(11) иди в курьеры - не позорься
13 stajer666
 
21.12.23
11:16
мужички, чего ж вы так обозлились, за неделю изучения я и так многое постиг, пришел вот к вам, за советом к старшим
14 Волшебник
 
21.12.23
11:18
(11) пустой цикл не надо было комментировать, его надо было наполнить смыслом
15 Eiffil123
 
21.12.23
11:45
(0) попробуйте что-то типа такого:



Процедура СформироватьОбъектОС(ПараметрыОС)
    
    СвойствоИдентификатора = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "ИнвНомераИзФайлаExcel");
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ОсновныеСредстваДополнительныеРеквизиты.Ссылка КАК Ссылка,
    |    ОсновныеСредстваДополнительныеРеквизиты.Свойство КАК Свойство,
    |    ОсновныеСредстваДополнительныеРеквизиты.Значение КАК Значение
    |ИЗ
    |    Справочник.ОсновныеСредства.ДополнительныеРеквизиты КАК ОсновныеСредстваДополнительныеРеквизиты
    |ГДЕ
    |    ОсновныеСредстваДополнительныеРеквизиты.Свойство = &Свойство
    |    И ОсновныеСредстваДополнительныеРеквизиты.Значение = &ИнвНомер";
    
    
    
    Запрос.УстановитьПараметр("Свойство", СвойствоИдентификатора);
    Запрос.УстановитьПараметр("ИнвНомер", ПараметрыОС.ИнвНомер);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        // Тут наверно ничего не делаем
        
    Иначе
        ОС = Справочники.ОсновныеСредства.СоздатьЭлемент();
        // Заполнение реквизитов
        //ОС.Наименование = ...
        //ОС. ....    
        
        // Заполнение доп.реквизита:
        СтрокаДР = ОС.ДополнительныеРеквизиты.Добавить();
        СтрокаДР.Свойство = СвойствоИдентификатора;
        СтрокаДР.Значение = ПараметрыОС.ИнвНомер;
        СтрокаДР.ТекстоваяСтрока = ПараметрыОС.ИнвНомер;
        ОС.Записать();
    КонецЕсли;
    
КонецПроцедуры
16 stajer666
 
21.12.23
11:46
(15) спасибо! сейчас попробую
17 zelenprog
 
21.12.23
11:51
Посмотри, я когда-то делал процедуру для чтения доп-реквизитов для всех объектов, указанных в ТЗ:

Процедура ПолучитьДопРеквизиты_ДляТЗ (пТЗ, пКолонкаОбъекта, пТЗИмяДопРеквизитов)
    
    лМассивПартнеров = пТЗ.ВыгрузитьКолонку(пКолонкаОбъекта);
    
    пТЗДопРеквизитыКонтрагентов = УправлениеСвойствами.ЗначенияСвойств(лМассивПартнеров, Истина, Ложь);
    пТЗДопРеквизитыКонтрагентов.Индексы.Добавить("ВладелецСвойств, ИмяСвойства");
    
    Для Каждого лСтрокаТЗКонтрагенты из пТЗ Цикл
        Для Каждого лСтрокаТЗИмяДопРеквизитов из пТЗИмяДопРеквизитов Цикл
            
            лНазваниеКолонкиДопРеквизита = лСтрокаТЗИмяДопРеквизитов.ИмяРеквизита;
            лИмяРеквизитаДляРазработчика = лСтрокаТЗИмяДопРеквизитов.ИмяРеквизитаДляРазработчика;
            
            лПараметрыОтбора = Новый Структура("ВладелецСвойств, ИмяСвойства", лСтрокаТЗКонтрагенты[пКолонкаОбъекта], лИмяРеквизитаДляРазработчика);
            лМассивНайденныхСтрок = пТЗДопРеквизитыКонтрагентов.НайтиСтроки(лПараметрыОтбора);
            Если лМассивНайденныхСтрок.Количество() >= 1 Тогда
                лНайденнаяСтрока = лМассивНайденныхСтрок[0];
                лСтрокаТЗКонтрагенты[лНазваниеКолонкиДопРеквизита] = лНайденнаяСтрока.Значение;
            КонецЕсли;
            
        КонецЦикла;
    КонецЦикла;
    
КонецПроцедуры

Описание параметров:
пТЗ - это ТаблицаЗначений. Одна из колонок - это объекты БД, для которых нужно найти допреквизиты (*).
      Другие колонки - куда будут записаны доп-реквизиты (**).
      Колонки могут иметь произвольные названия.
пКолонкаОбъекта - это имя колонки в пТЗ, в которой записаны объекты, для которых нужно найти допреквизиты (*).
пТЗИмяДопРеквизитов - это имена колонок в пТЗ, которые нужно заполнить значениями допреквизитов (**).
18 stajer666
 
21.12.23
11:56
(17) и тебе огромное спасибо!
как что-то дельное выйдет, сразу отпишу
19 Donkey_hot
 
21.12.23
11:56
(0) Пользуйтесь методами БСП и будет Вам счастье.
20 Donkey_hot
 
21.12.23
11:58
(11) А чего там возиться, Вам нужно две функции - ЗначениеСвойства() и ЗаписатьСвойстваУОбъедка()
21 zelenprog
 
21.12.23
12:00
(17)+
Пример использования этой процедуры:

1) создаешь ТЗ, например вот такой структуры:
    МояТЗ = Новый ТаблицаЗначений;
    МояТЗ.Колонки.Добавить("Контрагент");
    МояТЗ.Колонки.Добавить("GUIDГрузополучателя");
    МояТЗ.Колонки.Добавить("GUIDМеркурий");

2) Записываешь в колонку "Контрагент" те объекты, для которых будешь искать доп-реквизиты

3) создаешь ТЗИмяДопРеквизитов

    ТЗИмяДопРеквизитов = Новый ТаблицаЗначений;
    ТЗИмяДопРеквизитов.Колонки.Добавить("ИмяРеквизита");
    ТЗИмяДопРеквизитов.Колонки.Добавить("ИмяРеквизитаДляРазработчика");
    //----
    лСтр = ТЗИмяДопРеквизитов.Добавить();
    лСтр.ИмяРеквизита = "GUIDГрузополучателя";
    лСтр.ИмяРеквизитаДляРазработчика = "GUIDГрузополучателя_8030890e1ef34e218ad492c1a44ea512";
    //----
    лСтр = ТЗИмяДопРеквизитов.Добавить();
    лСтр.ИмяРеквизита = "GUIDМеркурий";
    лСтр.ИмяРеквизитаДляРазработчика = "GUIDМеркурий_6e5828b4732c437dbdf8a76fb81e9db2";

4) Вызываешь процедуру:

ПолучитьДопРеквизиты_ДляТЗ (МояТЗ, "Контрагент", ТЗИмяДопРеквизитов).

У меня работает.
22 zelenprog
 
21.12.23
12:02
(20) Я когда-то очень долго искал эти две функции. Пришлось рыться по общим модулям.
Познание БСП - это процесс очень долгий.

Кстати, есть какое-нибудь более-менее полное описание БСП?
23 Donkey_hot
 
21.12.23
12:08
(22) Документация на ИТС недостаточно полна, с Вашей точки зрения?
24 stajer666
 
21.12.23
12:14
(20) тут все несколько сложнее
у меня есть отдельная процедура для записи всех остальных реквизитов, комментариев, сообщений для пользователей и тд

я сначала пытался через функция возвращать значение истина/ложь, есть ложь - создаем новый элемент, истина - ничего не делаем

как бы саму таблицу значений с доп.реквизитами из БСП у меня получалось вытащить, прописывал потом поиск строк, но чет не хотел работать тот вариант, не знаю, что было не так
25 zelenprog
 
21.12.23
12:30
(23) Не всегда удобно сидеть в интернете на сайте.
Иногда хочется взять что-то типа книги. Или в бумажном в виде, или в электронном.
26 zelenprog
 
21.12.23
12:30
(24) А что сейчас не получается?
27 stajer666
 
21.12.23
12:33
(26) думаю, сейчас все будет норм, дорабатываю процедуру из (15) , чтобы у меня все корректно записывалось
28 stajer666
 
21.12.23
17:16
в общем, сделал я)

такая вот функция

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

и такая обработка дальше

УжеЕстьТакаяНоменклатура = ПроверкаИнвентароногоНомера(ПолученныйИнвНомер);
......

ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "ЛСИнвНомераИзФайлаExcel");
                    ЕстьСтроки = ОбъектОС.ДополнительныеРеквизиты.НайтиСтроки(Новый Структура("Свойство", ДопРеквизит));//Пусть результатом поиска будут "ЕстьСтроки"
                    Если ЕстьСтроки.Количество() = 0 Тогда
                        СтрокаТЧ = ОбъектОС.ДополнительныеРеквизиты.Добавить();
                        СтрокаТЧ.Свойство = ДопРеквизит;
                    Иначе
                        СтрокаТЧ = ЕстьСтроки[0];
                    КонецЕсли;
                    СТрокаТЧ.Значение = ПолученныйИнвНомер;
                    ОбъектОС.Записать();

                иначе
                    Сообщить("Уже есть " + ПолученныйИнвНомер);
29 Donkey_hot
 
21.12.23
17:26
(28) И, видимо, все это мероприятие в цикле?
30 bolobol
 
21.12.23
17:36
Переделать!
31 Eiffil123
 
21.12.23
17:51
(29) объектов ос наверняка не так уж много (не более 100к), чтоб обращать внимание на оптимизацию кода
32 Волшебник
 
21.12.23
22:35
(31) Запросы в цикле потом войдут в привычку
33 Волшебник
 
21.12.23
22:40
Нейронка запомнит, что запросы циклах работают и так нормально. В 90% случаев так и будет. Сервера будут справляться, потому что базулька будет целиком помещаться в память.
34 stajer666
 
22.12.23
09:05
(31) конкретно для ОС не наберется и 300 элементов, а за раз планируется записывать по 20-30 позиций
35 stajer666
 
22.12.23
09:12
(30) друг, так предложи свой вариант решения, я ж не против посмотреть

знал бы, как сделать лучше - так бы и поступил, а так это мой первый опыт в 1с, хочется получить хотя бы рабочий вариант
AdBlock убивает бесплатный контент. 1Сергей