Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.04.2007, 18:23   #1
Тимониссимо
 
Регистрация: 10.04.2007
Сообщений: 4
По умолчанию Delphi 7 + access + excel = out of memory

программер я плохой, но диплом писать надо...
Смысл проги такой: есть таблица access со стат данными про предприятия (7 показателей за каждый квартал с 2000 по 2006 год, итого, 1000 строк и ок. 200 столбцов).
Соединяюсь через ado, Делаю выборку из таблицы (выбрать предприятия опред. отрасли и района). Данные отображаются в dbgrid. Далее перегоняю в обычный массив.
Затем создаю E:=CreateOleObject('Excel.Applicati on'); Пергоняю из массива в ячейки активной книги.
В итоге, после увеличения файла подкачки до 1 Гб прога начала работать (Athlon 2.0, 512 озу). Exe-ник соответственно тоже не запускается на средник по мощности компах.
Не могу также при перегоне из массива в excel заполнить одну ячейки в строке (заголовки к таблице) - в этом случае гига оперативы не хватает!
Короче, подскажите, что делать, плз!!!
Вот код программы:
Код:

var
  Form1: TForm1;
  nachalo, konec, kolzap, i, j: integer;
  e,sheet:variant;
  mas_data: array [1..10000, 1..10000] of real;
  mas_data2: array [1..10000, 1..10000] of real;
  mas_data3: array [1..10000, 1..5] of string;
  odna_firma: string;
  mas_pokaz: array [1..7] of string = ('Прибыль','Отгрузка','Обор. активы','Собст. кап.','заим. кап','бюдж. зад','кратк. зад');

procedure TForm1.Button3Click(Sender: TObject);
var
  perem, otrasl: string;
  perem2, perem1, k, pi,pj: integer; // для города
  otr1, otr2:integer; //для отрасли

begin
  perem:=unit1.Form1.DBLookupComboBox1.Text; // считали название города
  with unit2.DataModule2.ADOQuery_town do //выбираем код города в соотв. с выбранным названием
  begin
    active:=false;
    sql.Clear;
    sql.Add('select * from soato');
    sql.Add('where name like '''+perem+'''');
    active:=true;
  end;
  perem:=unit2.DataModule2.ADOQuery_town.Fields[0].AsString; //считываем код города
  if form1.CheckBox1.Checked=false then
    begin
      perem2:=strtoint(perem)+1999;
      perem1:=strtoint(perem)-1;
    end
  else
    begin
      perem2:=strtoint(perem)+1;
      perem1:=strtoint(perem)-1;
    end;
  //----------- закончили с городом -----------------//
---
  //-------------- закончили с отраслью -------------//

 with unit2.DataModule2.ADOQuery1 do
  begin
    Active:=false;
    datamodule2.ADOQuery1.Parameters.ParamByName('kodtown1').Value:=perem1;
    datamodule2.ADOQuery1.Parameters.ParamByName('kodtown2').Value:=perem2;
    datamodule2.ADOQuery1.Parameters.ParamByName('otr1').Value:=otr1;
    datamodule2.ADOQuery1.Parameters.ParamByName('otr2').Value:=otr2;
      // unit1.Form1.Edit2.Text:=unit2.DataModule2.ADOQuery1.SQL.GetText;
    active:=true;
    unit1.Form1.Edit2.Text:=inttostr(unit1.Form1.DBGrid1.DataSource.DataSet.RecordCount);
 end;

//------------ начинаем отбор по периоду ----------------//
    kolzap:=unit1.Form1.DBGrid1.DataSource.DataSet.RecordCount;
    nachalo:=(strtoint(form1.ComboBox2.Text)-2000)*28+7*(strtoint(form1.ComboBox1.Text));
    konec:=(strtoint(form1.ComboBox4.Text)-2000)*28+7*(strtoint(form1.ComboBox3.Text)+1)-1;
       //---- создаем книгу excel ----//
    E:=CreateOleObject('Excel.Application');
    e.workbooks.add(-4167);
    e.workbooks[1].worksheets[1].name:='лист1';
    sheet:=e.workbooks[1].worksheets['лист1'];
     //------ считываем dbgrid (только 7 показателей) -----------------------//
    sheet.cells[1,1]:='код ОКПО';
    ...
    sheet.cells[1,6]:='Адрес';
    k:=7;
       //------ заголовки первый прогон -------//

     pi:=strtoint(form1.ComboBox1.Text);
     pj:=strtoint(form1.ComboBox2.Text);
    sheet.range['A1:Gs1'].font.bold:=true;
    with unit2.DataModule2.ADOQuery1 do
      begin
        first;
        for i:=1 to kolzap do
          begin
mas_data2[i,1]:=fields[0].AsFloat;  sheet.cells[i+1,1]:=mas_data2[i,1];
mas_data2[i,2]:=fields[1].AsFloat;  sheet.cells[i+1,2]:=mas_data2[i,2];
mas_data2[i,3]:=fields[2].AsFloat;  sheet.cells[i+1,3]:=mas_data2[i,3];
mas_data2[i,4]:=fields[3].AsFloat;  sheet.cells[i+1,4]:=mas_data2[i,4];
mas_data3[i,1]:=fields[4].AsString; sheet.cells[i+1,5]:=mas_data3[i,1];
mas_data3[i,2]:=fields[5].AsString; sheet.cells[i+1,6]:=mas_data3[i,2];
            k:=7;
            for j:=(nachalo-1) to (konec-1) do
              begin
                mas_data[i,j]:=fields[j].AsFloat;
                sheet.cells[i+1,k]:=mas_data[i,j];
                k:=k+1;
              end;
            moveby(1);
          end;
      end;
     //-------------- выгружаем нужное в excel -----------------//
      if form1.CheckBox3.Checked=true then
        e.visible:=true;
  end;

procedure TForm1.Edit4KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  with unit2.DataModule2.ADOQuery_firms do
  begin
    active:=false;
    sql.clear;
    sql.Add('select alldata.name');
    sql.Add('from alldata');
    sql.Add('where name like ''%'+unit1.Form1.Edit4.Text+'%''');
    active:=true;
  end;
end;
Тимониссимо вне форума Ответить с цитированием
Старый 13.04.2007, 08:53   #2
Трофимов Александр
Форумчанин
 
Аватар для Трофимов Александр
 
Регистрация: 03.11.2006
Сообщений: 321
По умолчанию

В SQL не силён, но могу сказать, что в Вашей программе проблема в подходе к решению, надо не загонять данные в массив:
for i:=1 to kolzap do
begin
mas_data2[i,1]:=fields[0].AsFloat; sheet.cells[i+1,1]:=mas_data2[i,1];
mas_data2[i,2]:=fields[1].AsFloat; sheet.cells[i+1,2]:=mas_data2[i,2];
mas_data2[i,3]:=fields[2].AsFloat; sheet.cells[i+1,3]:=mas_data2[i,3];
mas_data2[i,4]:=fields[3].AsFloat; sheet.cells[i+1,4]:=mas_data2[i,4];
mas_data3[i,1]:=fields[4].AsString; sheet.cells[i+1,5]:=mas_data3[i,1];
mas_data3[i,2]:=fields[5].AsString; sheet.cells[i+1,6]:=mas_data3[i,2];
k:=7;
for j:=(nachalo-1) to (konec-1) do
begin
mas_data[i,j]:=fields[j].AsFloat;
sheet.cells[i+1,k]:=mas_data[i,j];
k:=k+1;
end;

а записи нужные сразу скидывать в нужный файл.
Трофимов Александр вне форума Ответить с цитированием
Старый 13.04.2007, 14:26   #3
Virtson
Владимир М.
Участник клуба
 
Аватар для Virtson
 
Регистрация: 30.10.2006
Сообщений: 1,289
По умолчанию

исправления :
1) сделать нормальную реляционную БД, а не все в одной таблице хранить.
2) использовать саму БД () или файлы для промежуточной обработки данных.
3) генерировать файл xml вместо xls, и потом вызвать метов saveas Excel.Application - xls и получим.
/ заполнение по ячейкам книги в памяти 1000 строк - это изврат.
сам так раньше делал /
Берегите друг друга!
Virtson вне форума Ответить с цитированием
Старый 23.04.2007, 18:00   #4
Prisian
Пользователь
 
Регистрация: 23.04.2007
Сообщений: 38
По умолчанию

Попробуй свою базу в Access экспортировать в таблицы Paradox7-8 или DBase. Потом в Database desctop отредактировать. А в DBGrid с помощью объекта TTable установить в поле Database свою базу
Prisian вне форума Ответить с цитированием
Старый 27.04.2007, 20:55   #5
BBKey
Новичок
Джуниор
 
Регистрация: 25.04.2007
Сообщений: 1
По умолчанию

О! Люди, а не подскажете как правильно выкидывать данные в excel массивом, а то я пробовал, че-то не получается, пришлось по ячейкам данные вносить.
BBKey вне форума Ответить с цитированием
Старый 06.07.2008, 07:16   #6
_Engine_
Форумчанин
 
Регистрация: 29.06.2008
Сообщений: 603
По умолчанию

Цитата:
Сообщение от BBKey Посмотреть сообщение
О! Люди, а не подскажете как правильно выкидывать данные в excel массивом, а то я пробовал, че-то не получается, пришлось по ячейкам данные вносить.
Использовать объект Range.
Например, так:
Uses ComObj;
...

var FBuffer, RANGE, CELL1, CELL2 : Variant;
...

FBuffer := VarArrayCreate([1, 100, 1, 100l], varVariant);
for i := 1 to 100 do
for j := 1 to 100 do
FBuffer[i,j] := Random;
CELL1 := FWorkBook.WorkSheets[1].Cells[1, 1];
CELL2 := FWorkBook.WorkSheets[1].Cells[100, 100];
RANGE := FWorkBook.WorkSheets[1].Range[CELL1, CELL2];
RANGE.Value := FBuffer;
_Engine_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
экспорт отчета из Access 2007 в Excel. Возможно? perlik0 Microsoft Office Access 2 21.07.2008 13:18
Memory Leak Старовъръ БД в Delphi 2 14.07.2008 20:01
Экспорт из Access в Excel, Экспорт из отчётов в таблицу Excel Kissedbythegod Microsoft Office Access 1 31.05.2008 22:15
PrtScSysRq vs Memory JoanM Общие вопросы Delphi 17 10.01.2008 09:06