Имя: Пароль:
1C
1С v8
Получить все реквизиты и их значения для любого документа
,
0 Fanyn
 
12.08.15
13:08
Добрый день.
Мне необходимо получить все реквизиты и их значения для любого, выбранного пользователем, документа. Названия реквизитов я получила. Подскажите, пожалуйста как получить их значения и стоит ли для значений создать отдельный массив или же создать Таблицу Значений?
P.S. кодить на 1с только начала. Почти ничего не знаю :( Заранее спасибо!

&НаСервере
Функция МассивИменРеквизитовОбъекта(Объект)
        МассивИменРеквизитов = Новый Массив;
                 
            МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
                     
        Для индекс = 0 по 1 Цикл
            КоллекцияРеквизитов = ?(индекс=0, МетаданныеОбъекта.СтандартныеРеквизиты, МетаданныеОбъекта.Реквизиты);
            Для каждого Реквизит из КоллекцияРеквизитов Цикл
                МассивИменРеквизитов.Добавить(Реквизит.Имя);
            КонецЦикла;
        КонецЦикла;
        
        Для Каждого ТабличнаяЧасть Из Объект.Метаданные().ТабличныеЧасти Цикл
        Для Каждого РеквизитТЧ ИЗ ТабличнаяЧасть.Реквизиты Цикл
                   МассивИменРеквизитов.Добавить(РеквизитТЧ.Имя);
            Сообщить(" - " + РеквизитТЧ.Имя);
        КонецЦикла;
    КонецЦикла;
    
        Возврат МассивИменРеквизитов;
    КонецФункции
1 Fanyn
 
12.08.15
13:09
Для получения названий реквизитов использую выше указанный код.
2 jsmith82
 
12.08.15
13:10
Муторно как-то. Лучше звёздочкой
3 1Сергей
 
12.08.15
13:12
а ничо, что имена реквизитов в шапке и в табличных частях могут совпадать?
4 Fanyn
 
12.08.15
13:13
(2) Извините, я нуб, поэтому нужно разжевать :)

МассивИменРеквизитов.Добавить(РеквизитТЧ.*);
            

В данной строке?
5 jsmith82
 
12.08.15
13:13
(4) Не-не, ты чо
6 Fanyn
 
12.08.15
13:14
(3) Абсолютно согласна, но пока не считаю это таким уж важным, как только получу значения реквизитов, вернусь к данной проблеме :)
7 jsmith82
 
12.08.15
13:14
Запрос = Новый Запрос();
Запрос.Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок КАК Док";
Запрос.Текст = СтрЗаменить(Запрос.Текст, "%ИмяДок", ИмяДок);
8 Fanyn
 
12.08.15
13:15
(5) мне потом эти реквизиты в файл записать нужно будет
9 jsmith82
 
12.08.15
13:15
Ну, и в текст запроса можно добавить поля, которых не хватает. Не помню щас, нужно ли табличные отдельно прописывать, но там тоже будет через скобку и *.
10 jsmith82
 
12.08.15
13:16
Хотя для табличных частей лучше свои отдельные таблицы. Запрос на шапку и запросы на каждую ТЧ. Выгрузка в ТЗ, доступ к именам колонок через Колонки.
11 magicSan
 
12.08.15
13:19
Какая страшная логика у человека "МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Объект));"
12 jsmith82
 
12.08.15
13:20
(11) Ну да, проще Объект.Метаданные()
13 magicSan
 
12.08.15
13:21
(12) Это логичнее поэтому для нормальных выглядит как проще
14 magicSan
 
12.08.15
13:22
ей же написано значения объекта - как вообще до такой уйни можно было додуматся?
15 Fanyn
 
12.08.15
13:24
(14) до этого я код не писала вообще, запросы строила с помощью Схемы компоновки данных. До того что есть додумалась с помощью гугла и аналогичных тем на форумах :)
16 Fish
 
12.08.15
13:25
(14) Может, где-то набор новичков идёт и это у них тестовые задания? Недавно похожее что-то было:
Как получить все строковые реквизиты?
17 jsmith82
 
12.08.15
13:26
Мтд = Объект.Метаданные();
Массив = Новый Массив();

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();

Структура = Новый Структура("Имя, ТЗ", ТабЧасть.Имя, ТЗ);
Массив.Добавить(Структура);

Для Каждого ТабЧасть из Мтд.ТабличныеЧасти Цикл

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок.%ИмяТабЧасти КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", ИмяДок);
Текст = СтрЗаменить(Текст, "%ИмяТабЧасти", ТабЧасть.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();

Структура = Новый Структура("Имя, ТЗ", ТабЧасть.Имя, ТЗ);
Массив.Добавить(Структура);

КонецЦикла;
18 jsmith82
 
12.08.15
13:28
Мтд = Объект.Метаданные();
Массив = Новый Массив();

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();

Структура = Новый Структура("Имя, ТЗ", "Шапка", ТЗ);
Массив.Добавить(Структура);

Для Каждого ТабЧасть из Мтд.ТабличныеЧасти Цикл

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок.%ИмяТабЧасти КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
Текст = СтрЗаменить(Текст, "%ИмяТабЧасти", ТабЧасть.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();

Структура = Новый Структура("Имя, ТЗ", ТабЧасть.Имя, ТЗ);
Массив.Добавить(Структура);

КонецЦикла;
19 Fanyn
 
12.08.15
13:33
(18) Ошибка передачи данныых.

{Форма.Форма.Форма(41)}: Ошибка при вызове метода контекста (МассивИменРеквизитовОбъекта)
    МассивРеквиз = МассивИменРеквизитовОбъекта(Док);
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
НачалоСвойства: ret    Форма: Элемент    Тип: {http://www.w3.org/2001/XMLSchema}anyType
по причине:
Ошибка преобразования данных XDTO:
НачалоСвойства: Value    Форма: Элемент    Тип: {http://www.w3.org/2001/XMLSchema}anyType
по причине:
Ошибка отображения типов:
Отсутствует отображение для типа '{http://v8.1c.ru/8.1/data/core}ValueTable'

Я с такой сталквалась, если в строке убрать Имя после точки. Я так понимаю, он передает таблицу а ждет массив?

МассивИменРеквизитов.Добавить(РеквизитТЧ.Имя);
20 jsmith82
 
12.08.15
13:34
(19) не понял. код выложи функции
21 Fanyn
 
12.08.15
13:39
(20) код функции полностью ваш, только добавила строку после цикла

Возврат Массив;
22 Fanyn
 
12.08.15
13:42
(20)

&НаКлиенте
Процедура ВыгрузитьФайл(Команда)
        Док = Объект.Документ;
        типЗнач = ТипЗнч(Док);
        Запись = Новый ЗаписьТекста(Объект.ИмяФайла);
    Запись.ЗаписатьСтроку(Объект.Документ);
    Запись.ЗаписатьСтроку(типЗнач);
    МассивРеквиз = Новый Массив;
    МассивРеквиз = МассивИменРеквизитовОбъекта(Док);
    Для н=0 По МассивРеквиз.Количество()-1 Цикл
                    Запись.Записать(МассивРеквиз[н]+"="+"|");
        КонецЦикла;
    Запись.Закрыть();
КонецПроцедуры

    
&НаСервере
Функция МассивИменРеквизитовОбъекта(Объект)
    
      Мтд = Объект.Метаданные();
Массив = Новый Массив();

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();

Структура = Новый Структура("Имя, ТЗ", "Шапка", ТЗ);
Массив.Добавить(Структура);

Для Каждого ТабЧасть из Мтд.ТабличныеЧасти Цикл

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок.%ИмяТабЧасти КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
Текст = СтрЗаменить(Текст, "%ИмяТабЧасти", ТабЧасть.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();

Структура = Новый Структура("Имя, ТЗ", ТабЧасть.Имя, ТЗ);
Массив.Добавить(Структура);

КонецЦикла;
Возврат Массив;
    
    КонецФункции
23 jsmith82
 
12.08.15
13:43
&НаСервере
Функция МассивИменРеквизитовОбъекта(Объект)
Мтд = Объект.Ссылка.Метаданные();
Массив = Новый Массив();
...
24 jsmith82
 
12.08.15
13:43
Я написал для ОФ, а для УФ одну строчку изменил
25 jsmith82
 
12.08.15
13:44
Хотя тоже непонятно. Что за Объект.Документ
26 Fanyn
 
12.08.15
13:45
(25) Документ - это реквизит на форме обработки, документ выбираемый пользователем
27 jsmith82
 
12.08.15
13:47
А, понял, ТЗ на клиент идёт
28 jsmith82
 
12.08.15
13:47
ValueTable
29 jsmith82
 
12.08.15
13:49
Мтд = Объект.Метаданные();
Массив = Новый Массив();

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

Структура = Новый Структура("Имя, ТЗ", "Шапка", ТЗ);
Массив.Добавить(Структура);

Для Каждого ТабЧасть из Мтд.ТабличныеЧасти Цикл

Запрос = Новый Запрос();
Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок.%ИмяТабЧасти КАК Док";
Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
Текст = СтрЗаменить(Текст, "%ИмяТабЧасти", ТабЧасть.Имя);
Запрос.Текст = Текст;
ТЗ = Запрос.Выполнить().Выгрузить();
ТЗ = ИмяМодуля.ТаблицаЗначенийВМассив(ТЗ);

Структура = Новый Структура("Имя, ТЗ", ТабЧасть.Имя, ТЗ);
Массив.Добавить(Структура);
30 jsmith82
 
12.08.15
13:50
ИмяМодуля тут имя модуля в конфигурации, который содержит функцию ТаблицаЗначенийВМассив. Если типовая, то такой модуль должен быть. Сделай глобальный поиск. Если нет, скопируй из типовой. Там не должно быть ссылок на иные функции, а если и есть, то не больше одной-двух.
31 Fanyn
 
12.08.15
14:02
(30) я пишу внешнюю обработку, функцию в модуль обработки вставила. Где теперь посмотреть имя модуля для вставленной функции (конфигурация не типовая)
32 jsmith82
 
12.08.15
14:06
(31) найди в любой типовой. в УТ 11, в Бух 30
щас посмотрю у себя
33 Fanyn
 
12.08.15
14:08
(32) нашла, но проблема с переносом данных между клиентом и сервером осталась..
34 jsmith82
 
12.08.15
14:09
(33) Такого быть не могёт. Та же ошибка?
35 jsmith82
 
12.08.15
14:10
Кинь обработку, если чо
36 Fanyn
 
12.08.15
14:13
Могу, куда кинуть?
37 jsmith82
 
12.08.15
14:16
Пжжи
38 jsmith82
 
12.08.15
14:23
Понял, в чём ошибка. Щас
39 jsmith82
 
12.08.15
14:35
Мтд = Док.Метаданные();
    Массив = Новый Массив();
    
    Запрос = Новый Запрос();
    Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок КАК Док";
    Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
    Запрос.Текст = Текст;
    ТЗ = Запрос.Выполнить().Выгрузить();
    
    ТЗ1 = ТЗ.Скопировать();    
    Для Каждого Колонка Из ТЗ1.Колонки Цикл
        Если ТипЗнч(ТЗ[0][Колонка.Имя]) = Тип("ТаблицаЗначений") Тогда
            ТЗ.Колонки.Удалить(Колонка.Имя);
        КонецЕсли;
    КонецЦикла;    
    ТЗ = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТЗ);    
    
    Структура = Новый Структура("Имя, ТЗ", "Шапка", ТЗ);
    Массив.Добавить(Структура);
    
    Для Каждого ТабЧасть из Мтд.ТабличныеЧасти Цикл
        
        Запрос = Новый Запрос();
        Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок.%ИмяТабЧасти КАК Док";
        Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
        Текст = СтрЗаменить(Текст, "%ИмяТабЧасти", ТабЧасть.Имя);
        Запрос.Текст = Текст;
        ТЗ = Запрос.Выполнить().Выгрузить();
        ТЗ = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТЗ);
        
        Структура = Новый Структура("Имя, ТЗ", ТабЧасть.Имя, ТЗ);
        Массив.Добавить(Структура);
    КонецЦикла;
    
    Возврат Массив;
40 jsmith82
 
12.08.15
14:35
Запрос табличные части выгружал как таблицы значений. Надо было их удалить
41 jsmith82
 
12.08.15
14:36
Ну, конечно, сам сабж довольно спорен, в т.ч. под вопросом передача на клиент. Задача не ясна точно, но код рабочий
42 magicSan
 
12.08.15
14:42
Какие ужасы ..... может

об=Документы.ЗаказНаряд.НайтиПоНомеру("ПА0000050363");
для каждого й из об.Метаданные().Реквизиты цикл
Сообщить(""+й.имя+ " "+об[й.имя]);    
конеццикла;    

для каждого й из об.Метаданные().ТабличныеЧасти цикл
    Сообщить(" "+й.имя);
    тз=об[й.имя].выгрузить() //тч
конеццикла
43 jsmith82
 
12.08.15
14:45
(42) шо это было? О_о
44 magicSan
 
12.08.15
14:47
(43) Все реквизиты со значениями и тз табличных частей а чо ты там нагородил я хз - вырви глаз какой-то
45 jsmith82
 
12.08.15
14:54
(44) Ну ты скажешь тоже. Вывалил в окно служебных сообщений и празднуешь?
У меня хотя бы в удобоваримый класс пакуется, с которым работать можно
46 magicSan
 
12.08.15
14:58
(45) я хз куда там покавать и в каком виде это не приницпиально.

после такого

Текст = "ВЫБРАТЬ Док.* ИЗ Документ.%ИмяДок КАК Док";
    Текст = СтрЗаменить(Текст, "%ИмяДок", Мтд.Имя);
    Запрос.Текст = Текст;
    ТЗ = Запрос.Выполнить().Выгрузить();

надо руки отрезать ......
47 jsmith82
 
12.08.15
15:00
(46) чо те не нравится?
48 magicSan
 
12.08.15
15:02
(47) нахера брать все значения табличных частей документов типа объекта???
49 jsmith82
 
12.08.15
15:05
(48) Ессно нахера. Я же не экзамен сдаю ёптить. Написал от балды, чтобы тупо работало.
50 jsmith82
 
12.08.15
15:06
У тя так вообще хрен пойми чо написано. Вывалил в стек и доволен
51 jsmith82
 
12.08.15
15:06
)
52 magicSan
 
12.08.15
15:08
(50)     дерево=новый ДеревоЗначений;дерево.Колонки.Добавить("имя");дерево.Колонки.Добавить("зн");    
    об=Документы.ЗаказНаряд.НайтиПоНомеру("ПА0000050363");
    для каждого й из об.Метаданные().Реквизиты цикл
        Сообщить(""+й.имя+ " "+об[й.имя]);
        стр=дерево.Строки.Добавить();стр.имя=й.имя;стр.зн=об[й.имя];
    конеццикла;    
    
    для каждого й из об.Метаданные().ТабличныеЧасти цикл
        Сообщить(" "+й.имя);
        тз=об[й.имя].выгрузить(); //тч
        стр=дерево.Строки.Добавить();стр.имя=й.имя;стр.зн=тз;

    конеццикла
53 magicSan
 
12.08.15
15:09
(50) У меня 4 быстро работоющих строчки а твое Уг зависает...
54 jsmith82
 
12.08.15
15:09
(52) И что ты хотел этим доказать?
У меня ещё на клиент передаётся, а у тебя вырубится с ошибкой. Это тоже было в требованиях от ТС
55 jsmith82
 
12.08.15
15:10
Почему зависает-то? И там, и тут обращение к серверу. Кэшируется как-то круче у тебя?
56 jsmith82
 
12.08.15
15:11
Короче, раскритиковал мой код, сам ничё не предложил, чтобы отвечало требованиям, и раздулся от важности )
57 magicSan
 
12.08.15
15:13
(54) то вывод не нравится то передача на сервер - детский сад. такие мелочи самому не смешно ими аргументировать?

(55) Твое угу тянет все значения табличных частей - которыхх миллионы - какой нахер кэш??? тебя просили реквизиты и значения выбраного документы - чиатать научись - я это вывожу если ыт неспособен понять 4 строчки - в ясли.
58 jsmith82
 
12.08.15
15:16
(57) У тебя типа такая установка "вот вам код, если не работает или чёто не хватает, в ясли".
59 Fanyn
 
12.08.15
15:16
(56) Спасибо, проблема решена :)
Однако еще вопрос ТЗ записывается в двумерный массив (видимо) и когда я циклом пытаюсь записать ее в файл то записывается просто строка "Структура". Вы не подскажете как правильнее массив разобрать по столбцам?
60 jsmith82
 
12.08.15
15:18
(59) Ты как в файл записываешь? Строчно? Зачем? Сериализация не нужна? Задача просто показать, что умеешь?
61 Fanyn
 
12.08.15
15:21
(60) да, сериализацию использовать нельзя и функции записи xml.
В файл записываю строки:
Имя документа
Тип документа
Реквизиты в виде: имяреквизита=значение|имя=значение| И тд
62 Fanyn
 
12.08.15
15:22
(60)

Запись.ЗаписатьСтроку(Объект.Документ);
    Запись.ЗаписатьСтроку(типЗнач);
    МассивРеквиз = Новый Массив;
    МассивЗначений = Новый Массив;
    МассивЗначений = МассивЗначенийРеквизитовОбъекта(Док);
    МассивРеквиз = МассивИменРеквизитов(Док);
    Для н=0 По МассивРеквиз.Количество()-1 Цикл
        Для п=0 По МассивЗначений.Количество()-1 Цикл
                    Запись.Записать(МассивРеквиз[н]+"="+Строка(МассивЗначений[п])+"|");
                КонецЦикла;
                КонецЦикла;
    Запись.Закрыть();
63 Fanyn
 
12.08.15
15:22
Результат записи:

Кредитный договор 000000001 от 14.03.2013 0:00:00
Кредитный договор
Проведен=Структура|Ссылка=Структура|ПометкаУдаления=Структура|Дата=Структура|Номер=Структура|Клиент=Структура|Сотрудник=Структура|СуммаКредита=Структура|Ставка=Структура|Срок=Структура|
64 jsmith82
 
12.08.15
15:23
Щас скажу
65 jsmith82
 
12.08.15
15:29
Мас = МассивИменРеквизитов(Док);
Для Каждого Э0 Из Мас Цикл // Шапка и Табличные части
    Для Каждого ЭММ Из Э0 Цикл // Структуры (Имя табличной части (в т.ч. Шапки) и Коллекция значений)
        ИмяТабЧасти = ЭММ.Имя;
        Коллекция = ИмяТабЧасти.ТЗ; // Массив структур
        Для Каждого Стр Из Коллекция // Структура (бывшая строка таблицы значений)
            Для Каждого КлючИЗначение Из Стр // Разбор структуры
                ИмяРеквизита = КлючИЗначение.Ключ;
                ЗначениеРеквизита = КлючИЗначение.Значение;
            КонецЦикла;
        КонецЦикла;        
    КонецЦикла;
КонецЦикла;
66 jsmith82
 
12.08.15
15:30
Ну, а записать ставь там, где получаешь значение
67 Fanyn
 
12.08.15
15:48
(65) Ошибка:

{Форма.Форма.Форма(53)}: Итератор для значения не определен
    Для Каждого ЭММ ИЗ Э0 Цикл