2016-09-20 12 views
2

Я сохранил запись, содержащую таблицу TStringgrid в длинном блоке blob в таблице с в БД. Я извлекаю длинную блобу, хранящуюся в таблице, в БД, используя следующий код. Но, тем не менее, это очень медленно. Может ли кто-то предложить быстрый способ распечатать данные tstringgrid, хранящиеся в виде longblob в БД, на диаграмму в слове, используя delphi.Быстрый способ получить данные из Tstringgrid и заполнить полученные данные в диаграмме, содержащей слово

Field := mySQLQuery1.FieldByName('Table'); //Accessing the table field in DB 
blob := mySQLQuery1.CreateBlobStream(Field, bmRead); 
F := TStringList.Create; 
try 
    F.LoadFromStream(blob); //To load blob into string list 
    try 
    rowCount:= StrToInt(F[0])-1; //To get the total count of rows in string grid 
    colCount:= StrToInt(F[1]); //To get the total count of columns in string grid 

    aShape := WordApplication1.ActiveDocument.InlineShapes.Item(1); //To access the excel embedded chart in word 
    ashape.OLEFormat.Activate; 
    control2 := aShape.OLEFormat.Object_ as ExcelWorkBook; 
    AWorkSheet := control2.sheets['Table1'] as ExcelWorkSheet; //To access the sheet in word 
    except 
    on E: Exception do 
     MessageDlg(E.Message, mtInformation, [mbOk], 0); 
    end; { try } 

    i:= 2;   
    while i <= rowCount do 
    begin 
    str:=F[i + 2]; 
    //The values of each row stored in Tstringgrid for example are of the followingorder 
    //',,,,,,"0,00011","13,6714","0,00023","13,5994"' 

    for j := 1 to colCount do 
    begin 
     a:=pos('"',str); 
     b:=pos(',',str); 
     if (b<a) OR (a=0) then //To get and remove all null values by using searching for , delimiter 
     begin 
     if b=0 then substring:=str 
     else 
     begin 
      substring:=copy(str,0,pos(',',str)-1); 
      str:=copy(str,pos(',',str)+1,length(str)); 
     end; {if} 
     end {if} 
     else 
     begin //To get all values by using searching for " delimiter 
     str:=copy(str,pos('"',str)+1, length(str)); 
     substring:=copy(str,0,pos('"',str)-1); 
     str:=copy(str,pos('"',str)+2,length(str)); 
     end; {else} 
     if substring<> '' then 
     begin 
     AWorkSheet.Cells.Item[i, (j-6)].value := StrToFloat(substring); 
     end; 
    end; {for j} 
    i := i + 1; 
    end;{ while i} 
finally 
    F.Free; 
    freeandnil(blob); 
end; {try} 
+1

У некоторых профилирование. Определите, какая часть идет медленно. –

+0

У меня есть более 10000 записей. Это быстро, когда я иду с меньшим количеством записей. – mdel

+1

Угадайте, что узким местом, вероятно, являются вызовы 'AWorkSheet.Cells.Item [i, (j-6)]. Value: = StrToFloat (подстрока);', но вы действительно необходимо профайл, чтобы узнать, какая часть медленно. Есть полдюжины вещей, которые вы могли бы переписать или перепроектировать в этом коде выше, чтобы улучшить производительность в разных местах, но если вы не исправите медленную часть, вы просто слепите в темноте и, скорее всего, не добьетесь успеха. –

ответ

4

В соответствии с комментариями узким местом является назначение

AWorkSheet.Cells.Item[i, (j-6)].value 

в цикле. Это распространенная ошибка, возникающая при автоматизации Excel. Каждый вызов для автоматизации Excel несет значительную стоимость, потому что вы выполняете COM-вызов в другом процессе. В этом есть серьезные накладные расходы.

Вместо того, чтобы устанавливать данные с помощью N различных вызовов, по одному для каждой ячейки, задавать данные одним вызовом, который присваивает всем N ячейкам. Сделайте это, выбрав диапазон, представляющий всю целевую область рабочего листа, и назначьте массив вариантов, содержащий все N элементов за один вызов.

Некоторые примеры кода в этом ключе можно найти здесь: c++ Excel OLE automation. Setting the values of an entire cell-range 'at once'

+0

Нашли это спасибо http://stackoverflow.com/questions/16641897/export-delphi-stringgrid-to-excel – mdel