![]() |
![]() |
|
Недокументированная функция _StrToId() и _IdToStr() | ☑ | ||
---|---|---|---|---|
0
Torquader
10.04.09
✎
19:38
|
Возник вопрос с кодированием данных в текстовые строки.
Вспомнил, что есть функции _StrToId() и _IdToStr(), но что-то возникли проблемы с пониманием результата. Насколько я понял, _IdToStr() переводит число в 36-ричную систему ? И 00000 всегда 0. Далее, интересно, что _StrToId(-1) выдаёт какое-то значение, то есть отрицальность не проверяется ? Ожидалось, что _IdToStr() переводит число в "систему без ноля", как например нумерация колонок в Excel, но, видимо, ожидания не оправдались ? P.S. _StrToId("0000")=_StrToId("0") ??? |
|||
2
КонецЦикла
10.04.09
✎
19:48
|
Какой-то поток сознания...
Вот сам подумай 000 это число? Равно ли оно 0? |
|||
3
dk
10.04.09
✎
19:49
|
_idtostr("15") = F
_idtostr(15) = F _idtostr(0) = 0 _strtoid("F") = 15 _strtoid("f") = 0 ---- думай, решай, есть ограничения на длину |
|||
4
Torquader
10.04.09
✎
20:05
|
(2) я просто ожидал, что "000" != "00", но оказалось, что РАВНО.
Ограничения на длину там тоже странные - для целых положительных чисел ограничений нет. Все символы, кроме 1-9 A-Z считаются, как 0. Однако, _IdToStr(-1)=Z141Z3, а _StrToId("Z141Z3")=2118184959 удивляет то, что проверки на отрицательность аргумента нет. |
|||
5
Cthulhu
10.04.09
✎
20:59
|
Указанные функции служат для преобразования предствлений Id объектов данных (10-тичное представление - это формат внутреннего представления, из которых составлено ЗначениеВСтрокуВнутр(<объект данных>); 36-ричное представление -- это формат, в котором внутренние представления хранятся в таблицах базы данных) и метаданных 1с -- а вовсе не для преобразоывания чисел.. поэтому ожидать от них того, что они будут корректно преобразовывать отрицательные числа -- извините, но глупо... (кстати в равной мере глупо ожидать от этих функций преодразования Id, превышающих некоторые "граничные")
|
|||
6
Cthulhu
10.04.09
✎
21:01
|
(3): ограничения на длину легко вычисляются: 10 и 6
|
|||
7
orefkov
11.04.09
✎
09:33
|
(0)
Искренне завидиую - имееть время докапываться, почему недокументированные фичи 1С ведут себя не так, как ты ожидал - мне бы так. |
|||
8
orefkov
11.04.09
✎
10:12
|
Ладно уж, даю справку.
1. Всякий уважающий себя программист знает, что для 32-битных чисел в машинном виде -1 хранится точно также, как 0xFFFFFFFF (4294967295). Представление этого числа в 36ричной системе есть 1Z141Z3. 2. 1С для идшников используются только положительные знаковые целые (а не беззнаковые), то есть числа от 0 до 2147483647, то для их 36ричного представления отводится только 6 символов. Таким образом видно, что эти функции заточены именно под п.2, то есть всегда выдают результат 6-символной строкой. Поэтому в п. 1 ведущая 1ца откидывается. Обратное преобразование 36ричного числа Z141Z3 и есть 2118184959. Про "0000" и "0" даже не берусь пояснять. Это либо дано понять сразу, либо не понять никогда. |
|||
9
ДенисЧ
11.04.09
✎
10:15
|
(8) А вот философский вопрос... Если они отводят 6 знаков для ИД, то почему всё в базе лежит в char(9)...
|
|||
10
Ковычки
11.04.09
✎
10:18
|
(0) а как выглядят отрицательные значения к примеру в 16-и разрядной ?
|
|||
11
orefkov
11.04.09
✎
10:22
|
(9)
6 знаков идшник + 3 знака dbsign, код распределенной базы. И кстати, для хранения идшников объектов метаданных (ну там вид справочника и тп) отводится только 4 символа, отсюда видно, что максимальный возможный идшник для объекта метаданных есть _strtoid("ZZZZ") = 1679615. Берегите конфу, не правьте метаданные слишком часто, а то их тупо не хватит :) |
|||
12
Torquader
14.04.09
✎
22:12
|
А, кстати, об ИД-метаданных как раз вопрос и возник.
Как, не разбирая MD-файл, получить ИД-объекта метаданных и ИД-реквизита объекта. Для справочника, например, можно ValueToStringInternal(GetEmptyValue("Reference."+Metadata.Reference(i).Identifier)) в получаемом наборе четвёртый параметр обозначает ID справочника. А как получить ИД реквизита справочника ? (5) Внутри в базе всё хранится в двоичном представлении, так как функция _StrToId выдаёт не строку, а число, а число хранится внутри машины в том формате, который удобнее машине, а вот когда мы его хотим увидеть, нам машина выводит его в десятичном формате. Про _IdToStr меня поразило, что отрицательные числа переводятся не в 0, а также что _StrToId(_IdToStr(-1)) даёт число, которое никак на -1 не похоже, как его не переводи в 16 - мне стало интересно - почему так. (11) А почему для хранения типа "Неопределённый" используется 23+3 байта ? Я сколько ломал голову, так и не понял. Кстати, ValueFromStringInternal("{""UU"",""""}"); роняет 1С моментально. |
|||
13
Torquader
14.04.09
✎
22:14
|
(13) P.S. я пытаюсь написать систему логирования изменения объектов, которая будет "застрахована" от внесения изменений в конфигурацию, но пока получается только фигня.
|
|||
14
Guk
14.04.09
✎
22:15
|
(13) мне кажется ты придумываешь велосипед с трапециидальными колесами...
|
|||
15
ДенисЧ
14.04.09
✎
22:17
|
(13) надёжное логирование делается только через триггеры.
|
|||
16
Torquader
15.04.09
✎
16:56
|
(15) у меня семейство баз, причём разных, и не все даже 1С. Они работают вместе и обмениваются данными, при загрузке данных в 1С хочется, чтобы записывались данные об изменении определённых справочников, причём, если в конфигурации что-то поменяют, то система записи продолжала бы работать.
|
|||
17
Ёпрст
гуру
15.04.09
✎
17:00
|
>>>Берегите конфу, не правьте метаданные слишком часто, а то их тупо не хватит :)
Пять балов! :) |
|||
18
Mikeware
15.04.09
✎
17:03
|
(12) Ты не поверишь, но ПолучитьПустоеЗначение(вид) как раз берет ид из мд
Для хранения нопределенного 23 потому, что тип+вид+ид. |
|||
19
romix
модератор
15.04.09
✎
17:04
|
||||
20
ДенисЧ
15.04.09
✎
17:04
|
(16) Так сложно сделать автоматическую генерацию триггеров?
|
|||
21
Torquader
15.04.09
✎
17:16
|
(18) у меня как-то не получается 23:
ИД - 3+6=9 Вид=4 и откуда ещё 10 ? У меня было подозрение, что максимальное число - это 19 цифр+знак+точка=21 и ещё один байт признак типа. А там, если смотреть в DD получается 23+3 (насколько я понял, вторая часть - это органичение типа). (19) спасибо за ссылки - именно это я и пытался проверить. (20) у меня не SQL, а DBF-версия, причём часть из них вообще локальные однопользовательские, чтобы работали, когда отключат сеть - и весь этот зверинец, конечно, "глючит" так, что "мама не горюй". Возникла идея - хранить ID не в 36-ричной, а в 95-ричной системе (127-32), так они меньше места занимают. |
|||
22
ДенисЧ
15.04.09
✎
17:17
|
||||
23
Ёпрст
гуру
15.04.09
✎
17:19
|
ну тогда до кучи
http://www.script-coding.info/v77tables.html#1.1.1. |
|||
24
Torquader
15.04.09
✎
17:35
|
Больше всего радует 9 символов для хранения перечисления - обычно, элементы перечисления могут ограничиваться одним или двумя десятками.
|
|||
25
Mikeware
15.04.09
✎
17:37
|
(24) Общий принцип - если значение типизированное, то ид - 9 символов
|
|||
26
Torquader
15.04.09
✎
18:13
|
(25) понятно - просто обидно, когда куча места расходуется понапрасну.
Когда dbf размер файла быстро "накручивается" до двух гигов (особенно хороши строки неограниченной длины - все строки в одном файле) А конфу "беречь" не за чем - если мы что-то правим, то новые ID расходуются только на новые объекты, а если мы что-то переименовываем или меняем тип, то ID не меняется. |
|||
27
Torquader
15.04.09
✎
18:16
|
Вообще я уже понял, что или приводить всё в порядок, то есть ставить сервер и SQL, чтобы все "яйца в одной корзине" - просто и ясно, только вот денег это стоит.
|
|||
28
Cthulhu
15.04.09
✎
19:18
|
Mikeware, хорош пургу гнать...
1. Ид в виде внутреннего представдения объекта данных (ЛЮБОГО!) состоит из следующих частей: Ид типа объекта (1 символ) Ид вида объекта (10 символов) Ид объекта (10 символов) Код ИБ (3 символа) ИТОГО: 24 символа. 2. Этот Ид (внутреннего представления) для хранения в данных(!) раскладывается на составные части и сохраняется (в общем случае, причем не всегда полностью) в разных полях(колонках таблиц данных): Ид вида объекта - 4 символа(см.(11)), Ид объекта - 6 символов и Код ИБ (3 символа).. Иды вида объекта и объекта данных получаются из соответствующих частей Ид-а внутр.представления посредством _IdToStr(..). Отсюдова вывод: для оперирования объектами данных используется Ид из п.1 (единый собранный Ид фиксированной длины 24 символа); для поиска данных в таблицах данных нужно преобразовавать нужные составные чати этого Ид при помощи _IdToStr(..) и искать в соответствующих колонках таблиц данных (или писать в них))). |
|||
29
Torquader
15.04.09
✎
21:17
|
Да, 24 уже похоже на правду, хотя, вид объекта, всё-таки, должен быть 9 символов (он вообще 4, но 4 хранят в поле 9, почему-то).
|
|||
30
Torquader
15.04.09
✎
21:31
|
А IdToStr сдалась на 2147483649 (0x80000001)
Не совпало i=2147483649 => ZIK0ZL => -2147483647 То есть Id для 1С это четырёхбайтовое целое со знаком, но при этом отрицательные значения не допускаются. Удачи. |
|||
31
КонецЦикла
15.04.09
✎
21:36
|
(28) Вот значение в самую длинную строку БД, char(23)
'B1 NA 3X001 ' Не поднимай пыль |
|||
32
Torquader
15.04.09
✎
21:43
|
(31) он, видимо, считал не в упакованном виде, а в реальном (десятичные числа), только я как-то внутрь 1С настолько глубоко не лазил, чтобы увидеть, что там есть, а у функции ValueToStringInternal получается набор из семи параметров.
|
|||
33
КонецЦикла
15.04.09
✎
21:46
|
(32) Ну дык пора залазить :)
Внутри ж не десятичные, запаришься триггеровать |
|||
34
Torquader
15.04.09
✎
21:48
|
(33) конечно, хорошая идея - запускать отладку процесса 1С и ловить момент изменения данных, чтобы записать его в файл. Но это уже слишком - тормоза будут - просто супер.
|
|||
35
Sadovnikov
15.04.09
✎
22:06
|
Нда. Веселая веточка...
|
|||
36
Cthulhu
15.04.09
✎
22:12
|
(31): не надо бабушку лохматить, PARENTVAL - это не совсем ID (хотя и "по мотивам").
В базе все реквизиты агрегатных типов определенного вида хранятся в виде свернутого в 36-ричное представление Ид объекта данных (длина 6) +Код ИБ (три символа); объекты агрегатных типов не указанного вида хранятся в том же виде плюс(слева, в начало) 4-символьное 36-ричное представление Ид вида объекта... |
|||
37
orefkov
15.04.09
✎
23:10
|
(30)
Ты (8) что, невнимательно читал. Я это вроде там еще разъяснял. А 23 для неопределенных - ну видимо из расчета 'N' + 20 символов под число 19.9 + 2 про запас. |
|||
38
КонецЦикла
15.04.09
✎
23:28
|
(36) Об этом в курсе, зачем пудришь автору голову десятичными вещицами?
23 знака - это неопределенный тип как таковой (не только парентвал), проще уже так и хранить чем все время триммить при соединениях и проч. Если уж хранить неопределенное... а вообще я ниасилел что автор хочет сделать |
|||
39
Cthulhu
16.04.09
✎
12:50
|
(38): "десятичные вещицы" - суть внутреннее представление, как раз ералаш с разбивкой Ид внутреннего представления по полям(колонкам) таблиц бОльшее пудрение; и для правильной интерпретации Ид из колонок таблиц в данные(!!) агрегатных типов как раз через "денсятичные вещицы" только и решается.
23 знака - это НЕ Ид. Зранить неопределенное как раз лехко - в тех самых "числовых вещицах", которые для любого агрегатного типа данных одинаковой длины и структуры и позволяют выдернуть кратчайшим путем сам объект данных... ну или в более коротком виде, свернув в 36-ричное представление Ид вида (до 4 симв) и Ид объекта(до 6 симв). |
|||
40
Torquader
16.04.09
✎
21:05
|
(39) таки в памяти же хранится "объект", то есть структура данных - байтов.
И поля всех данных наверняка по 4 байта выровнены, чтобы процессору было удобно. Кстати, что у документов общий "номератор" ИД ? А у справочников, получается - у каждого свой. А во внутреннем представлении система различает документ, спозиционированный на определённом документе, и определённый документ (после CurrentDocument()). То есть там разные структуры. (38) автор хотел в другой базе данных сохранить ИД-объектов из базы 1С, чтобы было проще ссылаться на данные (просто есть объекты-справочники, у которых были отключены и код и наименование - и остаётся только ИД) - или добавить поле КОД (или КодУчёта) и перекодировать (занимает где-то 30 секунд на копии базы). А функцию IdToStr я перепутал с функциями нумерации колонок по Excel-евскому принципу - там без нуля, то есть сначала 0-9A-Z потом 00, и так далее. Получается шкала с геометрической прогрессией - которая ни в одну сторону быстро не преобразуется, но интересна тем, что в ней все символы значащие и не нужно передавать длину строки. |
|||
41
Torquader
16.04.09
✎
21:17
|
И ещё проблема в том, что в некоторых случаях применяется изменение номера или даты документа (резерв за вчера превращается в заказ сегодня просто переносом в другую дату и заменой номера, так как нумерация каждый день с единицы, и простановкой флага в работе).
Хотелось бы, чтобы другие системы, в которые попадает этот документ, понимали, что произошёл перенос, а не то, что создали новый документ. Эта проблема легко решается загоном всех пользователей в одну базу (видимо, из 1С будет устанавливаться соединение в SQL-сервером, в который будут отправляться изменения, а уже все остальные с этого сервера получат информацию). Если "сервер" навернётся, то просто перестанет работать обмен, потому как надёжность сети оставляет желать лучшего. Успехов в работе. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |