Guest |
Отправлено: 14.05.2004, 12:17 |
|
Не зарегистрирован
|
Есть Query1 через который идет запрос к таблице. Результат выводится в DBGrid. Как то, что в этом гриде сохранить хоть во что-нить.(txt,xls,doc,...)?
DBGrid позволяет сортировать записи? Чтобы не использовать Order by? |
|
Guest |
Отправлено: 14.05.2004, 12:55 |
|
Не зарегистрирован
|
DBGrid не позволяет сортировать записи — не его задача. DBGrid только показывает результаты выборки. Order by на SQL'евских базах самый эффективный способ сортировки, так как использует внутренние возможности сервера.
Чтобы слить DBGrid ->DataSource->DataSet во внешний файл надо поработать ручками. Проще всего в текстовый файл с фиксированными разделителями — его понимает Excel
CODE |
if (!DBGid? || ! DBGid?->DataSource) return;
TdataSet *ds = DBGid?->DataSource->DataSet;
if (!ds || !ds->Active) return;
ds->DisableControls();
for (ds->First(); !ds->Eof; ds->Next())
{
конкатенация всех полей кроме Memo,Blob и иже с ними AsString
запись полученной строки в файл
}
ds->EnableControls();
|
Я пользуюсь этим методом для экспорта в текст или Excel. Работает в сотни раз быстрее чем через COM сервер Excel’а.
Для экспорта в dbf некоторое время юзал ADO, но начались проблемы с настройкой и работоспособностью на разных машина — пришлось написать свой код для записи и чтения dbf файла. Вместо ADO можно использовать BDE у него есть интерпретатор SQL для разных форматов. Я стараюсь не использовать BDE — проблемы с настройкой при массовом тиражировании.
Удачи!
|
|
DVD |
Отправлено: 17.05.2004, 09:03 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
А, как сортировать по вычисляемому полю, созданному средствами Builder'a? Эти поля нельзя использовать в Order by. Поля, создаваемые в свойствах полей Query, вычисляемые в событии OnCalcField... |
|
olegenty |
Отправлено: 17.05.2004, 09:33 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
вряд ли есть такие вычисляемые поля, значения которых невозможно вычислить в запросе. а вот запрос позволяет и ORDER BY сделать :-))
|
|
Gedeon |
Отправлено: 17.05.2004, 10:12 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
QUOTE (DVD @ 17/05/2004, 10:05) | А, как сортировать по вычисляемому полю, созданному средствами Builder'a? Эти поля нельзя использовать в Order by. Поля, создаваемые в свойствах полей Query, вычисляемые в событии OnCalcField... |
Перекладывайте всю возможную работу с клиента на сервер. Вычисляйте поля там, и сортируйте соответственно.
|
|
DVD |
Отправлено: 17.05.2004, 15:51 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
ОК. Объясню. Есть база данных телефонных номеров. Номера зашифрованы простой операцией xor 1 на каждую цифру. Как мне в sql запросе выводить реальные номера телефонов? |
|
Gedeon |
Отправлено: 17.05.2004, 15:57 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
SQL | GO
SELECT a_int_value ^ b_int_value
FROM bitwise |
|
|
olegenty |
Отправлено: 17.05.2004, 15:57 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
чё за сервер у тебя?
напиши UDF (user defined function), и используй....
|
|
Guest |
Отправлено: 18.05.2004, 08:16 |
|
Не зарегистрирован
|
QUOTE | Есть база данных телефонных номеров. Номера зашифрованы |
А зачем вообще что то шифровать? Сервера БД позволяют закрыть от пользователя любую часть информации путем грамотной расстановки прав и создания View'ов.
Дополнительные преобразования над полем на стороне клиента причиняют много головной боли — нет сортировок, нет отбора по условию, нельзя делать связи и т.д.
Шифрование оправдано только в случае если вы хотите что бы кроме вашего приложения с этой базой никто не работал.
|
|
Gedeon |
Отправлено: 18.05.2004, 08:44 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Ну во первых хотелось бы действительно узнать че за сервер-то. Во вторых действительно зачем применять шифрование, если можно все закрыть на уровне сервера, а доступ кстати зарубить всем и давать его вообще только прриложению(SQL Server для других СУБД не знаю). Единственно шифрование применять только если хотите данные скрыть от админов, но зачем от них скрывать номера телефонов? Алгоритм шифрования достаточно прост и опытному человеку его достаточно просто расшифровать.
|
|
DVD |
Отправлено: 19.05.2004, 08:41 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
Какой сервер? Да кто его знает, по крайней мере не я. У меня просто есть на диске файлы dbf содержащие телефонную базу данных. В этой базе поле TEL поксорено на 1. Мне нужно написать прогу для работы с этой БД, используя SQL. Если не сложно объясните, как делать UDF? Я в SQL кроме SELECT, почти больше ничего незнаю. Если есть у кого доки про SQL в Билдере дайте линк или скиньте на мыло. |
|
DVD |
Отправлено: 19.05.2004, 08:44 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
QUOTE | SQL | GO
SELECT a_int_value ^ b_int_value
FROM bitwise |
|
А тип поля TEL string, как мне поксорить каждый символ? |
|
Gedeon |
Отправлено: 19.05.2004, 09:07 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
QUOTE | Какой сервер? Да кто его знает, по крайней мере не я. |
Приехали, а как, батенька мы к нему подключались?
QUOTE |
А тип поля TEL string, как мне поксорить каждый символ? |
В SQLServer это работает, как там в твоей базе, понятия не имею.
SQL | DECLARE @Test VARCHAR(10)
DECLARE @Int INTEGER
SET @Int = 3
SET @Test = '2334567'
SELECT @Test^3,@Int^1 |
|
|
AVC |
Отправлено: 19.05.2004, 09:13 |
|
Не зарегистрирован
|
Sorry. Речь шла только о SQL'евских серверах.
У вас не сервер а одиночный файл. В этом случае если не хотите иметь головной боли с шифорваной информацией — создайте новый файл (програмно) где это поле будет дешифровано и работайте с ним. На него можно понасоздавать разные индексы. Одиночную dbf таблицу удобнее юзать не через SQL а через компонент TTable.
Или вариант №2 — загнать эту таблицу на какой либо SQL'евский сервер, можно караманный типа IB, SybaseASA6/7, MaxDB(SupDB) и т.д. При использовании любого сервера будет больше хлопот по его обслуживанию, но можно будет пользоваться преимуществами SQL.
Ещё живой вариант — перегнать таблицу в MySql, а интерфейс писать на html
Выбор варианта зависит от назначения приложения. |
|
DVD |
Отправлено: 19.05.2004, 15:28 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
Так. А какими средствами можно сделать новый файл, в котором уже будет все поксорено? Я создаю вычисляемое поле. Нужный вид таблицы отображается в DBgreed. Вот. Как бы теперь этот грид сохранить в новый файл. То, как описано в начале, мне не очень понятно. Может кто даст рабочий вариант? Мне надо-то раз перегнать. Эх, а так бы я из адреса сделал поля для улицы, дома и квартиры.
Отредактировано DVD — 20/05/2004, 00:31 |
|
AVC |
Отправлено: 19.05.2004, 16:11 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Самый простой вариант:
1.Любым доступным средством типа DBed, DBU, Fox и т.д. на худой конец можно попробовать dbd из комплекта Bielder'а создаем в dbf дополнительные поля.
2.Открываем файл в проекте компонентом TTable.
3.Проходим по всем записям заполняя новые поля значениями.
4.Закрываем и тем же чем добавляли удаляем старые поля. |
|
DVD |
Отправлено: 21.05.2004, 06:20 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
Ок. Так сработало. А как, все таки, сохранять результаты запросов в файлы. Пробовал BatchMove, но он позволяет сохранять в форматы баз данных. А если мне xls,txt форматы нужны? |
|
olegenty |
Отправлено: 21.05.2004, 07:15 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
QUOTE |
А если мне xls,txt форматы нужны?
|
то
1. Напишешь руками. Это не сложно.
2. Воспользуешься, например, FastReport, он это позволяет...
|
|
AVC |
Отправлено: 21.05.2004, 07:40 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE | . А если мне xls,txt форматы нужны? |
См. ответ гостя в начале темы. |
|
DVD |
Отправлено: 21.05.2004, 09:34 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
То, что в начале написано я читал. Я не знаю, как сохранять в текстовом формате . Напишите рабочий вариант, пожалуйста.(тело цикла)
Отредактировано DVD — 21/05/2004, 18:40 |
|
AVC |
Отправлено: 21.05.2004, 10:14 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
CODE |
void __fastcall TForm1::Button4Click(TObject *Sender)
{
if (!DBGrid1 || ! DBGrid1->DataSource) return;
TDataSet *ds = DBGrid1->DataSource->DataSet;
if (!ds || !ds->Active) return;
FILE *fout = fopen("aaa.txt", "wb");
if (!fout) return;
try {
AnsiString rec; // буфер
AnsiString cdm = "\t"; // разделитель колонок
AnsiString rdm = "\r\n"; // разделитель срок
AnsiString str;
// Считаем что Memo,Blob и иже с ними в ds нет
rec = ""; // Title
for (int i=0; i < ds->FieldCount; i++)
{ str = ds->Fields->Fields[i]->DisplayName;
if(str.IsEmpty()) str = ds->Fields->Fields[i]->FieldName;
if (i) rec += cdm;
rec += str;
}
rec += rdm;
fwrite(rec.c_str(), rec.Length(), 1, fout);
ds->DisableControls();
for (ds->First(); !ds->Eof; ds->Next())
{ rec = "";
for (int i=0; i < ds->FieldCount; i++)
{ try { str = ds->Fields->Fields[i]->AsString; }
catch(...) { str = ""; }
if (i) rec += cdm;
rec += str;
} // ds->FieldCount
rec += rdm;
fwrite(rec.c_str(), rec.Length(), 1, fout);
} // !ds->Eof
ds->EnableControls();
} // try fopen
catch (...) { fclose(fout); throw; }
fclose(fout);
}
|
|
|