Имя: Пароль:
1C
1С v8
1с Заполнение табличной части
0 Wefast
 
07.12.16
15:44
Есть таблица в виде текстового файла. Колонки разделены ";"

Первая строка это названия колонок.

Программно формирую колонки. И вывожу их на форму.

Текстовыми данными заполняю таблицу. И пытаюсь заполнить 2 поля у строки с типом справочник.склад и спраовчник.контрагенты.
Но что то они не присваиваются и поля пустые.
Судя по сп нет каких то особых методов. Просто присваиваешь новое значение поля строки и все.
Что я делаю не так?

&НаКлиенте
Процедура ВыбратьФайл(Команда)
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Фильтр = "txt|*.txt";
    Диалог.Заголовок = "Выберите файл с накладными";
    Если Диалог.Выбрать() Тогда
        
        Текст = Новый ЧтениеТекста(Диалог.ПолноеИмяФайла);
        в = Текст.ПрочитатьСтроку();
        Если В<>Неопределено Тогда             
            СоздатьКолонки(В); // СОЗДАЮ КОЛОНКИ, и отображаю их на форме
            КолВоКолонок = СтрЧислоВхождений(В,";")+1;
            В = Текст.ПрочитатьСтроку();
            Пока В<>Неопределено Цикл
                КолонкиСтроки = ПолучитьКолонки();
                
                НоваяСтрока = Накладные.Добавить();
                Для каждого ЭлементСтроки из КолонкиСтроки Цикл
                    
                    Чч=Найти(В,";");    
                    Если Чч=0 Тогда
                        ИмяКол=В;
                    Иначе
                        ИмяКол=Лев(В,Чч-1);
                        В=Сред(В,Чч+1);
                    КонецЕсли;

// ТУТ пытаюсь заполнить реквезиты не строковыми значениями
// в итоге НоваяСтрока.Склад и Найденный элемент имеют имеют один тип.
                    Если ЭлементСтроки.Ключ = "agentname" Тогда
                        НоваяСтрока.Контрагент = НайтиЭлем(ИмяКол,"К");//Справочники.Контрагенты.НайтиПоНаименованию(ИмяКол);
                    ИначеЕсли ЭлементСтроки.Ключ = "sklad" Тогда
                        НоваяСтрока.Склад = НайтиЭлем(ИмяКол,"С");//Справочники.Склады.НайтиПоНаименованию(ИмяКол);
                    КонецЕсли;
                    НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
                КонецЦикла;
                
                В = Текст.ПрочитатьСтроку();
            КонецЦикла;
        КонецЕсли;
        
    КонецЕсли;
КонецПроцедуры



Процедура СоздатьКолонки(Колонки)
    
//Колонки это строга с названиями колонок
    Названия=Новый СписокЗначений;

    
// тут список значений с заголовками некоторых видимо фиксированных имен колонок и ТипыКол
    Названия.Добавить("data","Дата");        
    Названия.Добавить("id_doc","Номер"        );
    Названия.Добавить("nomer","Номер прод");         
    Названия.Добавить("sklad","Склад(солярис)");    
    Названия.Добавить("agentname","Поставщик");
    Названия.Добавить("summa","Сумма");      
    Названия.Добавить("summaz","Сумма");    
    Названия.Добавить("NDS10Z","НДС10");      
    Названия.Добавить("NDS18Z","НДС18");      
    Названия.Добавить("NDS10","НДС10 розн");  
    Названия.Добавить("NDS18","НДС18 розн");  
    Названия.Добавить("OSN","Осн.");        

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

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

// тут если правильно понимаю происходит отображение этих реквезитов на форме.
    Для каждого Колонка Из МоиРеквизиты Цикл
        Если Элементы.Найти("Накладные"+Колонка.Имя)<> Неопределено Тогда
            Элементы.Удалить(Элементы["Накладные"+Колонка.Имя]);
        КонецЕсли;
        Если Колонка.Имя = "Контрагент" Или Колонка.имя = "Склад" Тогда
            НовыйЭлемент = Элементы.Добавить("Накладные"+Колонка.Имя,Тип("ПолеФормы"),Элементы.Накладные);//,Элементы["Накладныеsklad"]);    
        Иначе
            НовыйЭлемент = Элементы.Добавить("Накладные"+Колонка.Имя,Тип("ПолеФормы"),Элементы.Накладные);
        КонецЕсли;
        НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
         НовыйЭлемент.ПутьКДанным = "Накладные."+Колонка.Имя;         
        НовыйЭлемент.ТолькоПросмотр = ИСТИНА;
        НовыйЭлемент.Заголовок = Названия.НайтиПоЗначению(Колонка.Имя);
                
    КонецЦикла;

КонецПроцедуры
1 DrShad
 
07.12.16
15:49
что в этой функции?

НайтиЭлем()
2 Wefast
 
07.12.16
15:50
(1) возвращает элемент справочника Склад или Контрагента
3 DrShad
 
07.12.16
15:52
(2) ты код покажи ибо не возвращает
4 Wefast
 
07.12.16
15:53
(3)
&НаСервере
Функция НайтиЭлем(Имя,Вид)
    
    Если Вид = "К" Тогда
        Э = Справочники.Контрагенты.НайтиПоНаименованию(Имя);    
    ИначеЕсли Вид = "С" тогда
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    СкладыДополнительныеРеквизиты.Ссылка
        |ИЗ
        |    Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
        |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Склады.ДополнительныеРеквизиты КАК СкладыДополнительныеРеквизиты
        |        ПО ЗначенияСвойствОбъектов.Ссылка = СкладыДополнительныеРеквизиты.Значение
        |ГДЕ
        |    ЗначенияСвойствОбъектов.Наименование = &Наименование";
        
        Запрос.УстановитьПараметр("Наименование", Имя);
        
        РезультатЗапроса = Запрос.Выполнить();
        Если РезультатЗапроса.Пустой() тогда
            Э = Справочники.Склады.ПустаяСсылка();
        Иначе
            Э = РезультатЗапроса.Выгрузить()[0].Ссылка;
        КонецЕсли;
    КонецЕсли;
    
    
    Возврат Э;
КонецФункции
&НаСервере
Функция ПолучитьКолонки()
    РеквезитыФормы = ПолучитьРеквизиты("Накладные");
    Колонки = Новый Структура();
    Для каждого К из РеквезитыФормы Цикл
        Колонки.Вставить(К.Имя,К.имя);    
    КонецЦикла;
Возврат Колонки;
КонецФункции
5 DrShad
 
07.12.16
15:54
да и вообще какое-то странное заполнение ТЧ у тебя выходит - все через клиента
6 DrShad
 
07.12.16
15:55
(4) какой ужас
7 DrShad
 
07.12.16
15:56
ГДЕ
        |    ЗначенияСвойствОбъектов.Наименование = &Наименование";

тут нужно не =, а ПОДОБНО
8 DrShad
 
07.12.16
15:56
тут
Если Вид = "К" Тогда
        Э = Справочники.Контрагенты.НайтиПоНаименованию(Имя);

заменить на

Если Вид = "К" Тогда
        Э = Справочники.Контрагенты.НайтиПоНаименованию(Имя, Истина);
9 DrShad
 
07.12.16
15:57
РезультатЗапроса = Запрос.Выполнить();
        Если РезультатЗапроса.Пустой() тогда
            Э = Справочники.Склады.ПустаяСсылка();
        Иначе
            Э = РезультатЗапроса.Выгрузить()[0].Ссылка;
        КонецЕсли;

заменить на

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
        Если НЕ Выборка.Следующий() тогда
            Э = Справочники.Склады.ПустаяСсылка();
        Иначе
            Э = Выборка.Ссылка;
        КонецЕсли;
10 DrShad
 
07.12.16
15:58
Э =

заменить на

Возврат
11 Wefast
 
07.12.16
15:58
(8) ну отладкой я смотрел Склад он находит тот что нужно. Но не присваивает его.
12 FIXXXL
 
07.12.16
16:00
(10) в хорошей функции - один Возврат :)

(11) тип колонки проверь, куда пишешь
13 DrShad
 
07.12.16
16:02
(11) а почему заполнение на клиенте?
14 DrShad
 
07.12.16
16:03
(12) ну конечно
15 Wefast
 
07.12.16
16:04
(9) а разница
(10)  не очень понял и что он вернет?
(12) ну в этом и загвоздка что тип один и тот же http://www.imageup.ru/img101/2622509/1234.png
16 Wefast
 
07.12.16
16:05
(13) Переделываю с 7 на 8. Просто так сделал, не задумывался на этот счет.
17 DrShad
 
07.12.16
16:06
(15) разница? выгрузка результата запроса в ТЗ, даже если в нем всего одна строка - медленнее чем обход выборки
18 DrShad
 
07.12.16
16:06
(15) если сделать как в (10) то из функции выйдет раньше - меньше строк обрабатываемого кода
19 DrShad
 
07.12.16
16:08
(15) типы то совпадают, но из-за того что заполняешь на клиенте не обновляя форму - ты их просто не видишь, а они есть )))
20 Wefast
 
07.12.16
16:11
(19) так я там же заполняю и текстовые реквезиты. И они видны.
(18) Куда его там впихнуть и для чего? Там вроде нет места откуда стоило бы выйти раньше. В любом случае, это же функция. Возврат требует выражения после себя.
21 DrShad
 
07.12.16
16:15
(20) ну так у тебя после каждого Э =  есть выражение
22 DrShad
 
07.12.16
16:17
блин, сразу не заметил

Если ЭлементСтроки.Ключ = "agentname" Тогда
                        НоваяСтрока.Контрагент = НайтиЭлем(ИмяКол,"К")//Справочники.Контрагенты.НайтиПоНаименованию(ИмяКол);

                    ИначеЕсли ЭлементСтроки.Ключ = "sklad" Тогда
                        НоваяСтрока.Склад = НайтиЭлем(ИмяКол,"С")//Справочники.Склады.НайтиПоНаименованию(ИмяКол);

                    КонецЕсли;
                    НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
23 DrShad
 
07.12.16
16:18
т.е. смотри  ты сначала по условию заполняешь Контрагент или Склад ссылкой и тут же после условия заменяешь на строку

НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
24 DrShad
 
07.12.16
16:18
Если ЭлементСтроки.Ключ = "agentname" Тогда
                        НоваяСтрока.Контрагент = НайтиЭлем(ИмяКол,"К"//Справочники.Контрагенты.НайтиПоНаименованию(ИмяКол);


                    ИначеЕсли ЭлементСтроки.Ключ = "sklad" Тогда
                        НоваяСтрока.Склад = НайтиЭлем(ИмяКол,"С"//Справочники.Склады.НайтиПоНаименованию(ИмяКол);


                    Иначе
                    НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
КонецЕсли;
25 DrShad
 
07.12.16
16:18
так перепиши
26 Wefast
 
07.12.16
16:23
(25) направил в нужном направление. Спасибо.

В своем случае заменил на кусок

                    Если ЭлементСтроки.Ключ = "agentname" Тогда                          
                        НоваяСтрока.Контрагент = НайтиЭлем(ИмяКол,"К");
                    ИначеЕсли ЭлементСтроки.Ключ = "sklad" Тогда
                        НоваяСтрока.Склад = НайтиЭлем(ИмяКол,"С");
                    ИначеЕсли ЭлементСтроки.Ключ = "Контрагент" или  ЭлементСтроки.Ключ="Склад" Тогда
                        Продолжить;
                    Иначе
                        НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
                    КонецЕсли;
27 DrShad
 
07.12.16
16:24
это совсем лишнее

ИначеЕсли ЭлементСтроки.Ключ = "Контрагент" или  ЭлементСтроки.Ключ="Склад" Тогда
                        Продолжить;

оно до него никогда не дойдет
28 DrShad
 
07.12.16
16:25
сорри на имена ключей не обратил внимания
29 Wefast
 
07.12.16
16:30
(21) т.е. вместо

           Э = Справочники.Склады.ПустаяСсылка();
        Иначе
            Э = РезультатЗапроса.Выгрузить()[0].Ссылка;
        КонецЕсли;

Нужжно:

          Возврат Справочники.Склады.ПустаяСсылка();
        Иначе
            Возврат РезультатЗапроса.Выгрузить()[0].Ссылка;
        КонецЕсли;

Это разве хоть как то оптимизирует код?

(27) Там все это происходит в переборе структуры со значениями колонок. Колонки Контрагент и Склад заполняются не из текстового файла а на основание одних из полей этого текстового файла. Т.е.
ЭлементСтроки.Ключ = "agentname"
должно заполнится два поля строки: agentname и контрагент в данном случае. Или номер по которому ищется склад и сам склад

И когда доходит перебор до ЭлементСтроки.Ключ="Контрагент" Заполнять НоваяСтрока[ЭлементСтроки.Ключ] таким образом уже не нужно, т.к. я уже заполнил к этому моменту это поле

Т.е. получается все таки надо так:

                    Если ЭлементСтроки.Ключ = "agentname" Тогда                          
                        НоваяСтрока.Контрагент = НайтиЭлем(ИмяКол,"К");
                    ИначеЕсли ЭлементСтроки.Ключ = "sklad" Тогда
                        НоваяСтрока.Склад = НайтиЭлем(ИмяКол,"С");
                    ИначеЕсли ЭлементСтроки.Ключ = "Контрагент" или  ЭлементСтроки.Ключ="Склад" Тогда
                        Продолжить;
                    КонецЕсли;
                    НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
30 Wefast
 
07.12.16
16:31
Не уверен в чем именно дело, но работает все это очень долго. Видимо все равно придется все переписывать
31 DrShad
 
07.12.16
16:32
ну и чем отличается это

Если ЭлементСтроки.Ключ = "agentname" Тогда                          
                        НоваяСтрока.Контрагент = НайтиЭлем(ИмяКол,"К");
                    ИначеЕсли ЭлементСтроки.Ключ = "sklad" Тогда
                        НоваяСтрока.Склад = НайтиЭлем(ИмяКол,"С");


от этого

НоваяСтрока[ЭлементСтроки.Ключ] = ИмяКол;
32 DrShad
 
07.12.16
16:32
двойное присвоение происходит
Закон Брукера: Даже маленькая практика стоит большой теории.