• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Fieldid в 1sblob.dbf

  • Автор темы LittleFairy
  • Дата начала
Статус
Закрыто для дальнейших ответов.
L

LittleFairy

Итак.
В известном файле имеется, например, строка реквизита "адрес" справочника "банки"
1W 8 0 23 114674, г.Москва, ул. Морская, д.49х остатков)
,где 1W - собственно значение поля FIELDID.
Проблема в том, что кривизна моих рук не позволяет мне получить значение FIELDID (не залезая в 1SBLOB, разумеется).
При использовании
ЗначениеВСтрокуВнутр(Спр) ,
где Спр = СоздатьОбъект("Справочник.Банки") получаю
"{"B","0","0","72","0","0"," 0 "}", но по-моему это не совсем то...
Спасите! :(
 
V

vbs

При использовании оператора
ЗначениеВСтроку(Спр.Адрес) ( а не ЗначениеВСтрокуВнутр)
получишь то, что надо
("строка","114674, г.Москва, ул. Морская, д.49х остатков")
А поле FIELDID - вещь в себе. Оно содержит строку из 4 знаков...
 
L

LittleFairy

Спасибо за ответ, но я , видимо не точно сформулировал проблему.
В итоге мне действительно нужно получить Спр.Адрес . Но проблема в том, что заранее мне неизвестны ни справочник, ни его реквизиты.
Я конечно могу их получить как строку, и получить значение реквизита через запрос.
Но реквизит Адрес имеет неограниченную длину ! А такой тип данных Запрос не поддерживает :) !
Я не вижу других путей получить такой реквизит, кроме как прямо из 1sblob.dbf.
И, если я все правильно понял именно значение поля FIELDID (в моем примере - 1W) связывает строку базы со справочником.
В примерах я видел, что ID получают из последней строки полученной ЗначениеВСтроку(Спр.Адрес) или ЗначениеВСтроку(Спр),
но во втором случае (как видно из 1го поста) последняя строка - это "0", а в первом я имею ЗначениеВСтрокуВнутр(Спр.Адрес) = "{"S","0","0","0","0","0","105554, г.Москва, ул. Садовая, д.77"}" , что меня несколько огорчает...
Да и вообще я себе не очень представляю, как я передам в функцию Спр.Адрес, только получив из метаданных строку "Адрес", говорящую о наличии такого реквизита...
 
V

vbs

заранее мне неизвестны ни справочник, ни его реквизиты
Что-то я не понимаю. Справочник имеет тип "Банки", там есть реквизит "Адрес". А по какому признаку ищется Адрес ? По Наименованию ? По коду ?
 
L

LittleFairy

ну это частный пример )
К слову это вроде как выгрузка должна быть )
Вообще перебираются справочники способом Метаданные.Справочник(Счетчик).
Потом у выбранных справочников берем имена реквизитов Метаданные.Справочник(НомерСпр).Реквизит(Счетчик) (ну или как-то так, нет кода перед носом )
И получается, что у меня только строка "Адрес" - идентификатор реквизита. Нет ни кода ни наименования, но они и не шибко нужны, т.к. хочется просто узнать, какие строки в 1sblob.dbf соответствуют реквизитам текущего справочника, а дальше вроде бы можно разобраться будет... :)
 
V

vbs

И все же хотелось бы понять, что происходит ?
Ну, перебираем справочники, внутри них реквизиты... А в какой момент и по какому критерию останавливаемся, чтобы что-то делать с адресом ?
 
L

LittleFairy

ну, если с самого начала, то дело обстоит так:
1) выдаем все справочники пользователю в списке значений
2) пользователь отмечает справочники, нужные для выгрузки (мы получаем идентификаторы в виде строк)
3) имея идентификаторы нужных справочников, находим в 1Cv7.DD соответствующие им файлы dbf, а из метаданных берем идентификаторы реквизитов
4) открываем найденный дбф и читаем все реквизиты, кроме строк неопределенной длины и периодических
5) и тут встает вопрос о том, как же мне достать реквизит, тип которого - строка неопределенной длины...
 
V

vbs

я бы сделал не так. Не выбирать реквизиты из файла, соответствующего справочнику, а собственно из справочника.
При этом сформировать файл DBF для этого справочника, и если там реквизит неопределенной длины - сформировать в файле обмена поле с запасом (например,300 символов). Периодические же реквизиты получать, например, на дату обмена.

Вот примерный кусочек кода для формирования структуры файла обмена:

Function CreateDBF()
Var k;
DBF.AddField("Group",1,1,0);
Ref = MetaData.Reference(НомерНужногоСправочика);
if Ref.CodeType = "Числовой" then
CodeType = 1
else CodeType = 2
endif;
CodeLength = Ref.CodeLength;
DescriptionLength = Ref.DescriptionLength;
DBF.AddField("Code",CodeType,CodeLength,0);
DBF.AddField("Descr",2,DescriptionLength,0);
for i = 1 to Ref.Attribute() do
RefAttr = Ref.Attribute(i);
Length = 0; Precision = 0;
if RefAttr.Type = "Число" then
Type = 1; Length = RefAttr.Length; Precision = RefAttr.Precision
elsif RefAttr.Type = "Строка" then
Type = 2; Length = RefAttr.Length;
if Length = 0 then Length = 200 endif; // для строк неопределенной длины
elsif RefAttr.Type = "Дата" then
Type = 3;
elsif RefAttr.Type = "Справочник" then
if EmptyValue(RefAttr.Kind) = 0 then // для справочников определенного вида
RefNumber = RefList.FindValue(RefAttr.Kind);
// элемент справочника я передаю кодом
Length = MetaData.Reference(RefNumber).CodeLength;
if MetaData.Reference(RefNumber).CodeType = "Числовой" then
if Length > 0 then
Type = 1;
else
Type = 2
endif;
else
Type = 2;
endif;
if Length = 0 then Length = 100 endif;
else
// для справочников неопределенного вида
Type = 2; Length = 100;
endif;
elsif RefAttr.Type = "Перечисление" then ,,// сохраняем номером
Type = 1;
Length = 3;

elsif RefAttr.Type = "Счет" then
Type = 2;
Length = 20;
endif;
DBF.AddField("Field"+String(i),Type,Length,Precision);
enddo;
if TrimAll(String(RefOwner)) <> "Метаданные" then
// для подчиненных справочников
OwnerNumber = RefList.FindValue(RefOwner); // владелец подчиненного справочника определяется на уровне перебора справочников по метаданным
CodeType = MetaData.Reference(OwnerNumber).CodeType;
CodeLength = MetaData.Reference(OwnerNumber).CodeLength;
if CodeType = "Числовой" then
CType = 1
else CType = 2
endif;
DBF.AddField("Owner",CType,CodeLength,0);
endif;
DBF.CreateFile(ИмяАрхива);
Message("Создан файл "+ИмяАрхива);
Return 1
EndFunction
//******************************************************************************
 
L

LittleFairy

Спасибо, попытаюсь переварить :)
Но вопрос "как же в принципе можно получить значение поля Fieldid в 1sblob.dbf для какого-либо объекта???" остается открытым...
 
V

vbs

собственно строки неограниченной длины в 1sblob живут в поле block, а так как оно имеет длину 80 символов, то все, что длиннее 80, живет где-то в других местах (Не знаю, как этот файл устроен). Вот поэтому-то с ним я бы и не стал связываться. Я использую для всех целей работы со справочниками самописную обработку, использующую файл обмена DBF, txt или xls. За три года вполне довел ее до ума и проблем не испытываю. В твоем случае я бы использовал нечто подобное - сформированные данные вывести в ТЗ, отметить нужные и далее их либо выгружать в содаваемый файл, либо загружать из сформированного файла. Все основано на структуре метаданных
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!