Имя: Пароль:
1C
1С v8
Восстановление документа из текстового файла
,
0 Plast1x
 
17.07.18
19:30
Добрый день, форумчане! Прошу сразу не пинать, так как новичок в 1С
Подскажите, пожалуйста. С помощью обхода документа по метаданным выгрузил в текстовый файл все реквизиты и ТЧ документа в виде:
Реквизит.Имя:Реквизит.Значение:Реквизит.Тип
Получились данные примерно такие:
КратностьДокумента:1:Число
Организация:Кондитер ООО:Организация
Склад:Основной склад:Склад

Вопрос в следующем: возможно ли вообще по этим данным создать копию исходного документа? На данном этапе у меня получается инициализировать документ нужно типа, но не понимаю, как привести к нужном виду и заполнить составные реквизиты (типо организации, склад и т.д)
Я пытался считывать из тестового файла все реквизиты. Заполняются только реквизиты с типом "Строка", что естественно, весь считываем строку.
Буду благодарен любым подсказкам! Заранее спасибо!
P.S. Такое задание, обязательное использование метаданных. Запрещено использовать УникальныйИдентификатор(), ЗначениеВСтрокуВнутр() и т.д
1 PR
 
17.07.18
19:33
Подсказка: грызи гранит дальше, в направлении непростых типов
2 Plast1x
 
17.07.18
19:44
(1) А по сути пока все правильно? Я смогу из таких данных создать новый документ? Или все - таки нужно исправить выгрузку в текстовый файл?
3 Lama12
 
17.07.18
19:44
Похоже твой сокурсник уже решал аналогичную задачу. В поиск.
Интересно почему нельзя использовать УникальныйИдентификатор()? Работа с кодами и наименованиями дает не однозначный результат. Может преподаватель хочет получит хэш функцию от того кто решает задачу? :-) (это я усложняю задачу).
Подсказка. Ищи способ идентифицировать объект сложного типа.
Заодно проверь, что-то у тебя не так. Кроме строк, должны еще были даты загружаться и числа. Обрати внимание на то, что неявное преобразование может не работать.
Вообще задачка муторная, но интересная для начинающего программиста. Если решишь сам, хорошо набьешь руку под структуризацию кода.
4 Lama12
 
17.07.18
19:46
(2) Надо исправлять. В выгрузке не полноценная информация о типе. "Организация" это может быть и справочники и перечисление (в общем случае).
5 Plast1x
 
17.07.18
20:44
(4) Благодарю. Буду пробовать выгрузить тип целиком
6 Garykom
 
гуру
17.07.18
20:58
(0) 1. Тип реквизита выгружать лишнее, они есть в метаданных и можно узнать при загрузке.

2. Для ссылочных типов выгружать наименование бесполезно, нужен УИД (странно что запрещено) или набор реквизитов однозначно идентифицирующих элемент некоего справочника (учти код может быть не уникальным как и наименование) или документ (аналогично дата+номер не факт что нет дублей)

3. Задача для правильного решения по переносу данных (в чистую базу или свой РИБ) должна решать проблему отсутствия там "непростых типов".
Надо сохранять все требуемые элементы справочников или документы (которые выбраны в документе) со всеми данными и там их восстанавливать если нет.
И тут встает проблема рекурсии (на каком уровне вложенности остановиться), когда реквизит исходного документа справочник, у этого справочника есть реквизит документ а там записана обратная ссылка на исходный документ ))
7 Lama12
 
17.07.18
21:14
(6) Я бы тип выгружал. Реквизит может быть составного типа.
Про рекурсию - да, веселая задачка. Особенно когда документ сам на себя ссылается в своем же реквизите.
8 Garykom
 
гуру
17.07.18
21:54
(7) Да про составные не подумал
9 Plast1x
 
18.07.18
00:22
(7) Извиняюсь за кучу вопросов, но снова встал в тупик...
Получилось выгрузить в полном виде тип. Итог такой:

ВалютаДокумента=руб.=Валюта=Справочник.Валюты
Организация=Организация ООО=Организация=Справочник.Организации
Склад=Основной склад=Склад=Справочник.Склады

Соответственно есть все реквизиты, дата, тип документа
Мне хватит этих данных для создания нового документа - копии?
И если не сложно, не могли бы подсказать, чем пользоваться для создания таких реквизитов с составным типом? Спасибо!
10 Plast1x
 
18.07.18
02:05
Документ инициализируется, заполняются все реквизиты, которые имеют простой тип (строки, числа, булевые)
Но вот реквизиты с типом, например, Справочник.Склады или Справочник.Организации не заполняются.
Может кто подсказать, как научить реквизит быть нужным типом, и как записать значение, если я его из файла считываю?
11 Маленький Мук
 
18.07.18
03:16
Знакомая задача, интересно кто так над студентами издевается.
12 hhhh
 
18.07.18
06:52
(10) а как ты заполняешь эти реквизиты? отсюда же не видно.
13 echo77
 
18.07.18
07:03
(0) Сериализовать объект в XML не проще? Или надо именно в текст выгрузить?
14 Plast1x
 
18.07.18
11:25
(13) Именно в текст. Таково задание(
(12) Так вот у меня и проблема с заполнением. Пытаюсь заполнить, обходя те же метаданные.

Для Каждого Реквизит Из НовыйДокумент.Метаданные().Реквизиты Цикл
        Строки = СтрЗаменить(Текст.ПрочитатьСтроку(),"=",Символы.ПС);
ЗначРек = СтрПолучитьСтроку(Строки,2);
НовыйДокумент[Реквизит.Имя] = ЗначРек;
КонецЦикла;

После этого, при просмотре созданного документа, реквизиты с простыми типами (строка, число) заносятся нормально, а вот реквизиты с типами Справочник.Организации и т.д остаются пустыми, т.к, скорее всего, пытаюсь занести в них строку, а это недопустимо(
15 Evgenchik
 
18.07.18
11:30
ЗначРек - это строка, а НовыйДокумент[Реквизит.Имя] - это например ссылка на справочник Организация.
Тебе надо найти нужную организацию из справочника по ЗначРек.
Искать по наименованию - не всегда найдется правильный элемент справочника, так как там бывают одинаковые имена. Поэтому нужно выгружать какой-то реквизит, по которому точно можно определить справочник. Если УИД нельзя, то я взял бы код
16 Plast1x
 
18.07.18
11:33
(15) Вот я и понимаю, что считывается просто строка. Мне бы понять, каким образом получить ссылку из строки. какими средствами? Буду благодарен, если подскажите
17 hhhh
 
18.07.18
11:36
(14) НовыйДокумент[Реквизит.Имя] = ЗначРек;

у тебя значрек - это ведь текстовая строка. В этом и проблема.

Ты тупо решил, что если в реквизит записать какую- то абракадабру, то вддруг там волшебным образом появится какое-то значение, элемент справочника, например.

Но в программировании так не делается. Ты должен

НовыйДокумент[Реквизит.Имя] =  писать сюда элемент справочнгика, а не любую абракадабру.
18 Builder
 
18.07.18
11:46
Уже расскажите ТС о функции
НайтиПоКоду(<Код>, <ПоискПоПолномуКоду>, <Родитель>, <Владелец>)
19 Builder
 
18.07.18
11:47
Есть еще синтаксис-помощник, там все написано с примерами.
Пример:
СтрокаКода = "840";
Валюты = Справочники.Валюты;
НайденнаяСсылка = Валюты.НайтиПоКоду(СтрокаКода);
Если НайденнаяСсылка = Валюты.ПустаяСсылка() Тогда
    Сообщить("Валюты """ + СтрокаКода + """ еще нет");
КонецЕсли;
20 hhhh
 
18.07.18
12:21
(18) не, ну него похоже НайтиПоНаименованию.
21 Plast1x
 
18.07.18
12:27
(20) Да, поиск по наименованию помогает, НО! У меня в файл записывается как бы в единственном числе
Справочник.Валюты
А для поиска необходимо, чтобы было Справочники.Валюты
По пробовал от руки в файле изменить, все хорошо заполняется. Но можно ли сделать так, чтобы в файл выгружался тип не в виде Справочник.Валюты, а именно Справочники.Валюты?
Выгрузку типа делаю следующим способом:

Для Каждого ТекТип Из РеквизитТЧ.Тип.Типы() Цикл
ТипРек = Метаданные.НайтиПоТипу(ТекТип).ПолноеИмя()
КонецЦикла;
22 FIXXXL
 
18.07.18
12:42
(16) Запросом получай
23 FIXXXL
 
18.07.18
12:49
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|    _Справочник.Ссылка КАК Ссылка
|ИЗ
|    "+МетаСправочник+" КАК _Справочник
|ГДЕ
|    _Справочник.Наименование = &НаименованиеИзФайла";

Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

вместо "МетаСправочник" подставляй свой "тип"
24 Plast1x
 
18.07.18
12:52
(23) У меня в файле реквизиты - это не обязательно справочник. Там есть и перечисления, и документы и т.д
25 hhhh
 
18.07.18
13:04
ну уже здесь проверяйте

Если Перем1 = "Справочник" Тогда
     Перем2 = "Справочники";
ИначеЕсли Перем1 = "Документ" Тогда
     Перем2 = "Документы";

и так далее
26 Plast1x
 
18.07.18
13:25
(25) Вот и я так думал, но может есть вариант порациональнее..Хотя в принципе главное, чтобы работало. Но это около 15-ти проверок надо сделать)
27 hhhh
 
18.07.18
13:28
(26) ну если меньше чем 5 миллионов проверок, то не парьтесь. 15 там или 115, какая разница.
28 Plast1x
 
18.07.18
14:17
(27) Ан нет, все равно столкнулся с проблемой..
Реквизит заносится нормально, если в программе указывать прямо:
Валюты = Справочники.Валюты;
НайденнаяСсылка = Валюты.НайтиПоНаименованию(РекЗнач);

Но я то считываю из файла строку "Справочники.Валюты". Т.е в итоге это тоже просто строка получается, а не ссылка. Можно ли как то переконвертировать что ли, чтобы, грубо говоря, запись
Перем1 = "Справочники.Валюты" была равна записи Валюты = Справочники.Валюты;
29 Kondarat
 
18.07.18
14:19
Менеджер = Справочники[ИмяСправочника]
НайденнаяСсылка = Менеджер.НайтиПоНаименованию(РекЗнач);
30 Plast1x
 
18.07.18
14:24
(29) Не подойдет( У меня реквизитов много в текстовом файле. Там есть и справочники, и документы, и перечисления...
31 Вафель
 
18.07.18
14:45
нужно было в xml выгружать
32 Serg_1960
 
18.07.18
14:54
"Именно в текст. Таково задание" - а кто Вам сказал, что XML это не текст? Формируешь штатно XML, а потом читаешь построчно и преобразуешь для выгрузки в свой... эээ.. "текстовый файл". Обратная операция (загрузка) будет допустима, если есть однозначное обратное преобразование в формат XML.
33 FIXXXL
 
18.07.18
14:54
(24) это просто образец, можешь описать весь кейс "типов" и дергать нужные функции

Если СтрНачинаетсяС(ТипИзФайла, "Справочник") Тогда
    НайтиСправочникСсылкуПоНаименованию(НаименованиеИзФайла);
ИначЕсли  СтрНачинаетсяС(ТипИзФайла, "Документ") Тогда
    НайтиДокументСсылкуПоНомеру(НомерИзФайла);
КОнецЕсли

но я бы переписал на ИДшники при выгрузке и использовал ПолучитьСсылку(<УникальныйИдентификатор>) ...
34 Serg_1960
 
18.07.18
14:59
Эээ... вообще-то в типовых всё нужное уже есть. Например, типа ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяОбъекта) и т.п.

Функция МенеджерОбъектаПоПолномуИмени(ПолноеИмя) Экспорт
    
    ЧастиИмени = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ПолноеИмя, ".");
    
    КлассОМ = ЧастиИмени[0];
    ИмяОМ   = ЧастиИмени[1];
    
    Если      ВРег(КлассОМ) = "ПЛАНОБМЕНА" Тогда
        Возврат ПланыОбмена[ИмяОМ];
        
    ИначеЕсли ВРег(КлассОМ) = "СПРАВОЧНИК" Тогда
        Возврат Справочники[ИмяОМ];
        
    ИначеЕсли ВРег(КлассОМ) = "ДОКУМЕНТ" Тогда
        Возврат Документы[ИмяОМ];
        
    ИначеЕсли ВРег(КлассОМ) = "ЖУРНАЛДОКУМЕНТОВ" Тогда
        Возврат ЖурналыДокументов[ИмяОМ];
        
    ИначеЕсли ВРег(КлассОМ) = "ПЕРЕЧИСЛЕНИЕ" Тогда
        Возврат Перечисления[ИмяОМ];
...
35 FIXXXL
 
18.07.18
15:23
(34) откуда у студента типовые? :)
36 Plast1x
 
18.07.18
15:39
(31) Выгружал бы, если б можно было
(32) Ну зачем вот этот пустой разговор. Задание конкретное, именно txt файл.
В итоге, я так понял, нельзя из строки "Справочники.Валюты" получить ссылку типа Валюта = Справочники.Валюта и потом делать поиск по наименованию?
Смысл то в том, что при создании нового документа, само представление документа то нам известно, его метаданные все известны. Следовательно и все метаданные реквизитов известны. Не могу понять, как конкретному реквизиту задать ссылку.
Если руками делать, то все понятно
Валюты = Справочники.Валюты;
НайденнаяСсылка = Валюты.НайтиПоНаименованию(РекЗнч);

Но у меня есть много реквизитов в файле, там и справочники, и документы. Их метаданные можно получить, но как задать именно ссылку - не понимаю( Уже голова кипит
37 Kondarat
 
18.07.18
15:43
(36) Вот ты упертый... Уже в нескольких постах есть ответы.

Менеджер = Справочники[ИмяСправочника]
НайденнаяСсылка = Менеджер.НайтиПоНаименованию(РекЗнач);

Менеджер = Документы[ИмяДокумента]
НайденнаяСсылка = Менеджер.НайтиПоНомеру(РекЗнач);

ПеречислениеСсылка = Перечисления[ИмяПеречисления]
- искать ничего не надо
38 FIXXXL
 
18.07.18
15:45
>Но у меня есть много реквизитов в файле, там и справочники, и документы.

Тебе все равно придется парсить строку "типа" реквизита и писать код на получение ссылки. Иначе - никак.

(37) он хочет без разбора "скармливать" платформе "Справочник.Валюты" и получать ссылки из воздуха :)
39 Plast1x
 
18.07.18
15:56
(38) Нет, не хочу. Я понимаю в чем моя тупость, поэтому и искал решение проблемы.
(37) Извиняюсь, что сразу не послушал. Сработало! Большое спасибо! Буду расписывать сейчас все остальное)
41 hhhh
 
18.07.18
16:36
(37) ПеречислениеСсылка = Перечисления[ИмяПеречисления]
- искать ничего не надо

уверен?
42 Kondarat
 
18.07.18
16:49
(41) Да, прав - ошибочка.

ПеречислениеСсылка = Перечисления[ИмяПеречисления][ЗначениеПеречисления]
43 Plast1x
 
18.07.18
17:08
(42) Это типо так?

ПеречислениеСсылка = Перечисления[ИмяПеречисления][ЗначениеПеречисления];
НовыйДокумент[Реквизит.Имя] = ПеречислениеСсылка;
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.