Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запись Variant в TMemoryStream, Хочу сбросить таблицу Access в бинарник 
V
    Опции темы
Steel
Дата 14.12.2011, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Здравствуйте. 
Пытаюсь заделать инструмент для перевода результата запроса (TADOQuery) к любой таблице БД Access в бинарный файл. 

Идея была в следующем:
1. Пройти по массиву полей Fields первой записи и сохранить в поток размеры полей, их имена и типы.
2. Идти по записям и сбрасывать в поток значения полей в соответствии с их размером.

Столкнулся с проблемой на втором шаге. У меня есть значения полей типа Variant (Fields[n].Value) и есть размер данных значений (Fields[n].DataSize), но я не могу эти значения записать. Если пытаюсь писать Fields[n].DataSize байт из Fields[n].Value - в поток пишется некая чушь, а не значение поля.

Вопрос: Как мне добыть нужное мне кол-во байт из типа Variant?
PM MAIL   Вверх
Snowy
Дата 14.12.2011, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 2
Всего: 484



Сначала присвой значение из вариант в переменную другого типа. Например в integer/string/array.
И записывай уже его. Обратно аналогично.
Поведение варианта не фиксировано и зависит от ситуации. Для записи в бинарный вид это не годится.
PM MAIL   Вверх
Steel
Дата 14.12.2011, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Тогда получается что я должен знать структуру таблицы. А я хотел сделать вариант именно для любой структуры.
Получается нету способа представить значение переменной типа Variant как к примеру массив байт?
PM MAIL   Вверх
Snowy
Дата 15.12.2011, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 2
Всего: 484



Ваиант меняет своё поведение в зависимости от ситуации.
А бинарная запись таких вольностей физически не может иметь.
В бинарной записи должно быть строгое определение, что писать.
Можно, конечно, конкретизировать поведение на уровне сериализации, но это будет ещё сложнее.
Могу предложить приводить все данные к string и писать их, как string.
PM MAIL   Вверх
Steel
Дата 15.12.2011, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



В общем при следующей реализации удалось свалить в бинарный файл таблицу с полями типа {DateTime, Single, Byte}

Код

var
  k   : Integer;
  FS  : TFileStream;
  Buf : array of Byte;
  Q   : TADOQuery;


Код

  k := Q.Fields[i].DataSize;

  SetLength(Buf, k);
  FillChar(Buf[0], k, 0);
  Q.Fields[i].GetData(Buf, False);

  FS.Write(Buf[0], k);

PM MAIL   Вверх
Steel
Дата 15.12.2011, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 14.5.2006
Где: Россия, Саратов

Репутация: нет
Всего: нет



Также провел эксперимент над TVarData. 
1. Присваивал значение переменной какого-либо типа.
2. Присваивал ее переменной типа Variant
3. Обнулял первую переменную
4. Копировал из TVarData(пременная типа Variant).VBytes[6] в буфер кол-во байт, соотвествующие типу иходной переменной.
5. Копировал столько же байт из буфера в исходную переменную
6. Проверял результат

Издевался над переменными типов {Integer, Word, LongWord, Byte, Double, Single}
В итоге в исходную переменную вернулось исходное значение во всех случаях, кроме того когда иходная переменная была типа Single.
Это случилось из-за того что сам Variant после присвоения ему такой переменной почему то считает себя Double.
Как это победить я не нашел. 

Код

var
  Val  : Variant;
  j    : Integer;
  i    : Integer;
  w    : Word;
  lw   : LongWord;
  si   : SmallInt;
  b    : Byte;
  d    : Double;
  s    : Single;
  bu   : array of Byte;
  rs   : String;
begin
  i  := -57890;
  b  := 232;
  d  := 4001.2345;
  s  := -4445.234;
  w  := 455;
  lw := 231233;
  si := 12341;
//  s := d;

  // ----------------------------------------------------
  Val := Unassigned;
  Val := i;
  i   := 0;
  j   := SizeOf(i);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], i, j);

  rs := 'i = ' + FormatFloat('0.00000', i);

  // ----------------------------------------------------
  Val := Unassigned;
  Val := si;
  si   := 0;
  j   := SizeOf(si);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], si, j);

  rs := rs + #13 + 'si = ' + FormatFloat('0.00000', si);

  // ----------------------------------------------------
  Val := Unassigned;
  Val := w;
  w   := 0;
  j   := SizeOf(w);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], w, j);

  rs := rs + #13 + 'w = ' + FormatFloat('0.00000', w);

  // ----------------------------------------------------
  Val := Unassigned;
  Val := lw;
  lw  := 0;
  j   := SizeOf(lw);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], lw, j);

  rs := rs + #13 + 'lw = ' + FormatFloat('0.00000', lw);

  // ----------------------------------------------------
  Val := Unassigned;
  Val := b;
  b   := 0;
  j   := SizeOf(b);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], b, j);
  rs := rs + #13 + 'b = ' +FormatFloat('0.00000', b);

  // ----------------------------------------------------
  Val := Unassigned;
  Val := d;
  d   := 0;
  j   := SizeOf(d);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], d, j);
  rs := rs + #13 + 'd = ' +FormatFloat('0.00000', d);

  // ----------------------------------------------------
  Val := Unassigned;
  Val := s;
  s   := 0;
  j   := SizeOf(s);

  SetLength(bu, j);
  FillChar(bu[0], j, 0);

  Move(TVarData(Val).VBytes[6], bu[0], j);
  Move(bu[0], s, j);
  rs := rs + #13 + 's = ' +FormatFloat('0.00000', s);

  ShowMessage(rs);
end;


PS использовал Delphi 2007
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.0463 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.