|
Как сериализовать несериализуемое системное перечисление? | ☑ | ||
---|---|---|---|---|
0
H A D G E H O G s
04.08.23
✎
16:22
|
Дня доброго.
В 1С есть особый класс значений, которые стоят особняком - интерфейсные перечисления, например: ВариантУправленияВысотойТаблицы (TableHeightControlVariant) Значения Авто (Auto) ВСтрокахТаблицы (UseHeightInTableRows) ВСтрокахФормы (UseHeightInFormRows) ПоСодержимому (UseContentHeight) Мне надо их значения сохранить в файл. Казалось бы, что может быть проще : Запись=Новый ЗаписьXML; Запись.УстановитьСтроку(); СериализаторXDTO.ЗаписатьXML(Запись,Значение); ТекстXML=Запись.Закрыть(); Но эти перечисления почти все не сериализуются. 1) В файл можно сохранить тип значения и значение строкой, например СтруктураСохранения=Новый Структура; СтруктураСохранения.Вставить("ТипЗначения",Строка(ТипЗнч(Значение))); СтруктураСохранения.Вставить("Значение",Строка(Значение)); НО! Функция Строка(Значение) очень (не очень) умно преобразует к перечислению вида "В строках формы". Окей, хлопец, убери пробелы и добавь заглавных букв. Но, есть перечисления, которые не просто расскладывают значение в читаемый текст, а добавляют знаки препинания. Не удобно делать обработку исключений. 2) Сохранять индекс значения перечисления. Самый заманчивый вариант, однако есть страх, что платформа его поменяет, внезапно, без объявления войны: СтруктураСохранения=Новый Структура; СтруктураСохранения.Вставить("ТипЗначения",Строка(ТипЗнч(Значение))); СтруктураСохранения.Вставить("Значение",ПолучитьИндексПеречисления(Значение)); 3) Сохранять строковое представление через ЗначениеВСтрокуВнутр(). Однако, тоже есть опасения, что это будет работать всегда: СтруктураСохранения=Новый Структура; СтруктураСохранения.Вставить("ТипЗначения",Строка(ТипЗнч(Значение))); СтруктураСохранения.Вставить("Значение",ЗначениеВСтрокуВнутр(Значение)); Пока колебаюсь между 2 и 3 вариантах, но может я что-то проглядел. |
|||
1
vicof
04.08.23
✎
16:25
|
4) Написать в 1с, чтобы сделали его сериализуемым)
|
|||
2
H A D G E H O G s
04.08.23
✎
16:27
|
(1) А ты неплох.
Кстати, частично они сериализуемые, например: ВертикальноеПоложение (VerticalAlign) Значения Верх (Top) Низ (Bottom) Центр (Center) Данный объект может быть сериализован в/из XML. Может использоваться в реквизитах управляемой формы. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data/ui}. Имя типа XDTO: VerticalAlign. Не знаю, по каким критериям они это делали, но мне надо все и сейчас. |
|||
3
Lama12
04.08.23
✎
16:29
|
(1) Это обязательно. Но задачу нужно решать сейчас.
(0) Я бы вторым вариантом решал. Легче анализировать имея информацию о версии конфигурации из которой производилась выгрузка. Так что если что-то изменится, можно и вручную проанализировать что изменилось и на что нужно заменить. |
|||
4
Гипервизор
04.08.23
✎
16:29
|
А можно пример с раскладкой с запятыми?
|
|||
5
Гипервизор
04.08.23
✎
16:31
|
Если надо прямщас, тогда я за вариант 2.
А уже потом думать над оптимизацией. |
|||
6
arsik
гуру
04.08.23
✎
16:41
|
(2) Наверно что в СКД можно использовать - то и сериализуется.
|
|||
7
rphosts
04.08.23
✎
16:43
|
2 + номер версии наборов значений...
|
|||
8
H A D G E H O G s
04.08.23
✎
16:44
|
(4) Строка(ВариантВыравниванияЭлементовИЗаголовков.ЭлементыЛевоЗаголовкиЛево)
Лево, заголовки лево |
|||
9
H A D G E H O G s
04.08.23
✎
16:45
|
(4) Там есть со скобками и вообще другими словами. На всякий случай предупреждаю.
|
|||
10
lubitelxml
04.08.23
✎
16:51
|
(0) СтруктураСохранения.Вставить("Значение",ЗначениеВСтрокуВнутр(Значение));
- а далее ЗначениеИзСтрокиВнутр() нормально отработает, или ты не в 1с передаешь? Если да, то почему бы и не использовать третий вариант и не привязаться к индексам? |
|||
11
RomanYS
04.08.23
✎
16:53
|
(0) в варианте 3 тип наверное не нужен, а так риски выглядит сравнимыми между 2 и 3
|
|||
12
H A D G E H O G s
04.08.23
✎
16:53
|
(10) По ощущениям ЗначениеВСтрокуВнутр/ЗначениеИзСтрокиВнутр 1C отнесла к устаревшим.
|
|||
13
lubitelxml
04.08.23
✎
16:54
|
(12) оно уже лет 15 как устарело... но все равно работает хорошо, сам проверял не так давно
|
|||
14
lubitelxml
04.08.23
✎
16:55
|
+(13) вместо него вроде как сделали XMLСтрока()
|
|||
15
H A D G E H O G s
04.08.23
✎
17:02
|
(14) xmlстрока() не работает с несериализуемыми
|
|||
16
arsik
гуру
04.08.23
✎
17:08
|
ЗначениеВСтрокуВнутр(Новый ХранилищеЗначения(Данные))
|
|||
17
RomanYS
04.08.23
✎
17:11
|
(12) оно всегда так было, с другой стороны вроде не было прецедентов, чтобы формат этой штуки менялся и она переставала работать.
Кстати ПолучитьИндексПеречисления() это по идее тоже себе задачка, или есть понимание как делать универсально? "Для каждого" работает в этих перечислениях? |
|||
18
arsik
гуру
04.08.23
✎
17:13
|
+(16) Но по сути он там хранит практически то что у тебя в вариант 3) описано
|
|||
19
arsik
гуру
04.08.23
✎
17:15
|
||||
20
H A D G E H O G s
04.08.23
✎
17:20
|
(17) для каждого работает. Через него и получим индекс
|
|||
21
lubitelxml
04.08.23
✎
17:20
|
Я сейчас ради интереса запустил глобальный поиск в УТ 11.5.12.60 по строке "ЗначениеВСтрокуВнутр" - у меня 51 строка найдена (где-то 10 - доработки, остальное типовое)
|
|||
22
H A D G E H O G s
04.08.23
✎
17:21
|
Наверное все же ЗначениеВСтрокуВнутр.
|
|||
23
Garykom
гуру
04.08.23
✎
17:21
|
(0) Напиши свой модуль сериализации
Внутри пока сделай на основе ЗначениеВСтрокуВнутр Потом если что поменяешь |
|||
24
lubitelxml
04.08.23
✎
17:22
|
(23) а как же микросервис на GO? )))
|
|||
25
Garykom
гуру
04.08.23
✎
17:23
|
(24) Он в Go не умеет, только в Delphi
|
|||
26
JanK
04.08.23
✎
17:34
|
(16) Смешно, да.
ЗначениеВСтрокуВнутр и ХранилищеЗначения используют один и тот же внутренний формат сериализации (ошибки десериализации из которого известны как "Ошибка формата потока"). Зачем в него 2 раза писать, чтобы надёжнее было? |
|||
27
mikecool
04.08.23
✎
18:00
|
(0) а в МЕтаданные из имена есть?
|
|||
28
Грю
04.08.23
✎
18:04
|
(0) Строка(Значение) - это как-то тупо выглядит. По крайней мере, если бы это было написано на другом ЯП.
Может лучше так? На JS я бы написал что-то типа того: Значение.Метаданные().Имя |
|||
29
H A D G E H O G s
04.08.23
✎
18:14
|
(27) Нет. Для интерфейсных перечислений не нашлось места в метаданных
|
|||
30
RomanYS
04.08.23
✎
18:17
|
(0) можно так еще
СтруктураСохранения=Новый Структура; СтруктураСохранения.Вставить("Тип", "Выражение"); СтруктураСохранения.Вставить("Значение", "ИмяПеречисления.ИмяЗначения"); и банальное вычилить для десериализации |
|||
31
H A D G E H O G s
04.08.23
✎
18:25
|
(30) Как ты получишь "ИмяЗначения" ?
|
|||
32
Грю
04.08.23
✎
18:33
|
По каким данным 1С сравнивает значения перечислений? Скорее всего, по типу и индексу. Значит индекс - первичен. Его и нужно сохранять.
Если в перечисление добавится новое значение, то что произойдет? Перечисления сдвинутся. А раз они сдвинутся в 1С, то в сериализованных данных они тоже должны сдвинуться. Единственный способ это получить - хранить индексы. |
|||
33
Гипервизор
04.08.23
✎
18:46
|
(0) А что за ПолучитьИндексПеречисления? Что это за зверь?
А если так? // На стороне источника ЗначениеИсточника = ВариантВыравниванияЭлементовИЗаголовков.ЭлементыЛевоЗаголовкиЛево; // например СтруктураСохранения = Новый Структура; СтруктураСохранения.Вставить("ТипЗначенияСтрокой", Строка(ТипЗнч(ЗначениеИсточника))); СтруктураСохранения.Вставить("ЗначениеСтрокой", Строка(ЗначениеИсточника)); // На стороне приемника СистемноеПеречисление = Вычислить(СтруктураСохранения.ТипЗначенияСтрокой); Для каждого ЭлементПеречисления Из СистемноеПеречисление Цикл Если Строка(ЭлементПеречисления) = СтруктураСохранения.ЗначениеСтрокой Тогда ЗначениеПриемника = ЭлементПеречисления; Прервать; КонецЕсли; КонецЦикла |
|||
34
Garykom
гуру
04.08.23
✎
18:53
|
(33) лучше индекс добавить и сначала по нему
а вот если не вышло то уже перебор и сравнение по строке |
|||
35
RomanYS
04.08.23
✎
19:15
|
(31) это же твоё же ПолучитьИндексПеречисления
|
|||
36
TormozIT
гуру
04.08.23
✎
19:24
|
ф = ПолучитьПолноеИмяПредопределенногоЗначения(ВариантУправленияВысотойТаблицы.ВСтрокахТаблицы)
|
|||
37
TormozIT
гуру
04.08.23
✎
19:26
|
(12) Я ее активно использую, но есть местами подводные камни, как например с сериализацией таблицы значений, которая включает внутренние номера строк и внутренний первый свободный номер строки.
|
|||
38
Гипервизор
04.08.23
✎
19:30
|
(36) Век живи.. Взял на заметку, благодарю.
|
|||
39
RomanYS
04.08.23
✎
20:52
|
(36) Супер!
(38) +1 |
|||
40
H A D G E H O G s
04.08.23
✎
23:24
|
(36) Огромное спасибо!
|
|||
41
Грю
05.08.23
✎
05:13
|
(40) Эй, ты реально так хочешь сделать? Уже же пояснили что нужно индекс хранить. Что если значение перечисления будет переименовано? Вместо "Вверх" станет "Наверх". Индексы при этом не изменятся, но имя изменится.
Всегда нужно хранить первичные данные, а не их представление. Это все равно что номенклатуру по названию искать, а не по коду. |
|||
42
ДедМорроз
05.08.23
✎
11:44
|
Было вверх,станет наверх.
Все равно весь код,который это использует,переписывать. |
|||
43
RomanYS
05.08.23
✎
12:07
|
(41) напомни, когда последний раз системные перечисления переименовывали. И что ты понимаешь под индексом? Имя значения и является его индексом в коллекции.
|
|||
44
vis
05.08.23
✎
16:01
|
(36) Век живи - век учись
|
|||
45
TormozIT
гуру
05.08.23
✎
18:35
|
Индекс у значений системных перечислений меняется намного чаще чем их имена.
|
|||
46
Кирпич
06.08.23
✎
08:37
|
(45) Да не меняются они вообще. Как написали структуру лет 20 назад, так и осталось. Вот прям программисту делать нечего, как сидеть и элементы структуры местами переставлять. А наименования менять - так это вообще рушить все конфы по всей стране.
|
|||
47
Грю
06.08.23
✎
08:54
|
(43) >> Имя значения и является его индексом в коллекции
На каком языке? Имя может быть любое: Up, Верх, и так далее. А индекс у них всегда одинаковый, хоть на китайском. Индекс - это индекс, очевидно же. Номер в виде числа. А имя - это имя. Это просто строка, к которой привязано число. |
|||
48
Грю
06.08.23
✎
08:58
|
(45) При смене индекса имя поменяется автоматически. Например:
Было: 1 - верх 2 - низ Стало: 1 - верх 2 - право 3 - низ И все что хранилось под номером 2, раньше было "низ", а потом сделалось "право". Потому что у низа индекс поменялся с 2 на 3. |
|||
49
Грю
06.08.23
✎
09:02
|
(46) Да, вероятность того что в перечисление добавится новое значение не в конец, а в середину, стремится к нулю. Поэтому и нужно использовать индексы, а не изобретать велосипеды с именами.
Имена перечислений - для программистов, чтобы было понятнее писать и читать программу. Машине они не нужны, она работает с числами. |
|||
50
PR
06.08.23
✎
10:30
|
(47) На английском, на каком же еще?
Попробуй сериализовать булево Что будет, 0 и 1 или все-таки false и true? |
|||
51
Chai Nic
06.08.23
✎
11:21
|
Помнится, в семерочном сериализаторе ЗначениеВСтрокуВнутр была недетерминированность сериализации. То есть, две сериализации одного и того же сложного объекта могли выдать разные строки, если одинаковые с точки зрения объектной модели объекты были заполнены в разном порядке (скажем, если сначала в ТЗ добавили колонку, а потом добавляли строки, или наоборот).
Интересно, как с этим в восьмерке? Какой-нибудь метод сериализации гарантирует детерминированность, чтобы можно было например сравнивать сложные объекты не обходя их, а через сравнениях их сериализаций как строк? |
|||
52
RomanYS
06.08.23
✎
15:09
|
(47) Для меня индекс это то, что можно поставить в выражение Коллекция[Индекс].
Попробовал для теста ВариантУправленияВысотойТаблицы[0] - получил ошибку, и документации никаких упоминаний, что "для каждого" выдает значения в гарантированном порядке. Да и вообще немного странно перебирать значения, когда можно без этого обойтись. |
|||
53
Грю
06.08.23
✎
18:57
|
(50) Почему тогда не Истина и Ложь? Вот! Потому что название не совпадает со значением.
|
|||
54
Грю
06.08.23
✎
18:59
|
(51) Сериализация не предназначена для сравнения. Если строки и будут совпадать сегодня, то не гарантируется что и завтра они совпадут.
|
|||
55
Грю
06.08.23
✎
18:59
|
(52) Ну это же 1С, тут все не как у людей. Понять и простить.
|
|||
56
Chai Nic
06.08.23
✎
19:10
|
(54) Надо чтобы гарантировалось. Иначе это плохая, негодная сериализация)
|
|||
57
Грю
06.08.23
✎
22:03
|
(56) Не годная для сравнения строк. А для обмена данными годная.
|
|||
58
Chai Nic
07.08.23
✎
06:35
|
(57) Полезно было бы иметь каноническую сериализацию, гарантирующую повторяемость, именно для того чтобы сравнивать объекты без обхода. И например, хранить только уникальные предыдущие версии, без разбора и парсинга.
|
|||
59
1snik_d
07.08.23
✎
09:52
|
(58) Писать свой сериализатор
|
|||
60
DrZombi
гуру
07.08.23
✎
10:13
|
(0) Держи. Может на мысли наведет.
Функция ПолучитьЗначенияПеречисленияПоИдентификатору(пНазваниеИдентификатораCOM_Перечисления, ИмяПеречисления) ЗначенияМета = Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления.Найти(пНазваниеИдентификатораCOM_Перечисления); Если ЗначенияМета = Неопределено Тогда Возврат Перечисления[ИмяПеречисления].ПустаяСсылка(); КонецЕсли; Возврат Перечисления[ИмяПеречисления][ЗначенияМета.Имя]; КонецФункции Функция ПолучитьНазваниеИдентификатораПеречисления(COM_ЗначениеПеречисления,БазаИсточник) Возврат Строка(БазаИсточник.String(БазаИсточник.XMLСтрока(COM_ЗначениеПеречисления))); КонецФункции |
|||
61
H A D G E H O G s
07.08.23
✎
10:18
|
(60) интерфейсных перечислений нет в метаданных
|
|||
62
Гипервизор
07.08.23
✎
10:18
|
(60) Что-то не наводит на мысли, а как это прицепить к системным перечислениям? В метаданных их нет, метода Найти() у них нет.
|
|||
63
RomanYS
07.08.23
✎
10:22
|
(60) Зачем во второй функции двойное приведение к строке, разве XMLСтрока может вернуть что-то другое?
|
|||
64
программистище
07.08.23
✎
10:23
|
(61) а что за задача такая, сериализовать интерфейс?
может тогда ручная сериализация подойдет? или обязательно нужно бучу на 1с разводить?))) |
|||
65
Chai Nic
07.08.23
✎
10:34
|
(59) Это не быстро, хотелось бы платформенное решение
|
|||
66
1snik_d
07.08.23
✎
10:52
|
(65) Ну если универсально под все случаи, то долго. А так для конкретных хотелок можно и написать
|
|||
67
RomanYS
07.08.23
✎
10:58
|
(66) так (0) и пишет условно сериализатор. Чтобы написать всё равно нужны инструменты на уровне платформы.
|
|||
68
DrZombi
гуру
07.08.23
✎
10:59
|
(61) Придумай ;)
|
|||
69
DrZombi
гуру
07.08.23
✎
11:00
|
(62) Что поделать, мысль, она у как вдохновение, все время витает %)
|
|||
70
DrZombi
гуру
07.08.23
✎
11:02
|
(63) Через КОМ, может. Честно, не помню, тогда отладчику было виднее. Сейчас просто, что наросло, тем и пользуюсь, не теряя времени на вопросы о былом.
|
|||
71
DrZombi
гуру
07.08.23
✎
11:02
|
+(61) Напиши свое перечисление, которого нет, и обрабатывай так как тебе его надо обработать :)
|
|||
72
H A D G E H O G s
07.08.23
✎
11:25
|
(71) Какой то поток альтернативного разума.
|
|||
73
H A D G E H O G s
07.08.23
✎
11:25
|
(64) Сохранять настройки элементов форм.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |