| 
| 
 | Вопрос # 1 776/ вопрос открыт / | 
 |  Здравствуйте, эксперты!Появилась необходимость создавать отчёт в Excel.Просветите меня пожалуйста,как более предпочтительнее его создавать,с помощью OLE XLApp:=CreateOleObject('Excel.Application');
 или с помощью компонента TExcelApplication
 ExlApp:=TExcelApplication.Create(Self);
 Если можно поподробней достоинсва и недостатки обоих методов.И ещё не дадите ли ссылки на примеры и статьи в которых есть перевод макросов записанных в Excel на delphi.Особенно меня интересует
 - выделение,удаление и вставка столбца
 -запись формулы применительно к столбцу
 -представление в столбце данных в формате времени
 
|  |   Вопрос задал: GAZ (статус: Посетитель)Вопрос отправлен: 19 июля 2008, 10:33
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: ANBsoft Здравствуйте, GAZ!Насчет достоинств сказать не могу, сам работал только через OLE.
 Но насчет макросов могу сказать, что они переводятся очень легко.
 Фактически Excel это объект со своими свойствами, методами и пр.
 При работе берем макрос записанный в VBA и просто меняем синтаксис на паскалевский:
 "=" на ":=", скобки массива "(" и ")" на "[" и "]".
 Часто Excel использует свои константы, например:
 Range("B2:C6").Select
 Selection.Borders(xlEdgeTop).LineStyle = xlNone
 With Selection.Borders(xlEdgeBottom)
 .LineStyle = xlContinuous
 .Weight = xlThin
 .ColorIndex = xlAutomatic
 End With
 В таком случае прямо в Excele выполняем примерно такое Cells(1,1)=xlContinuous
 и все остальное тоже и выясняем значения этих констант.
 Можно один раз объявить их у себя и в дальнейшем не думать об этом:
 const
 xlChart = -4109;
 xlDialogSheet = -4116;
 xlExcel4IntlMacroSheet = 4;
 xlExcel4MacroSheet = 3;
 xlWorksheet = -4167;
 ................. и так далее.
 В моей практике таким образом преобразовавается 90-95% макросов VBA.
 Бывают более сложные случаи, например создание объектов на листе (кнопок и пр), а также присвоения им макросов, но это более редкий случай, для отчетов это как правило не нужно.
 
|  | Ответ отправил: ANBsoft (статус: Студент)Время отправки: 19 июля 2008, 11:18
 Оценка за ответ: 5
 |  
 Мини-форум вопросаВсего сообщений: 8; последнее сообщение — 20 июля 2008, 11:32; участников в обсуждении: 3. 
|   | GAZ (статус: Посетитель), 19 июля 2008, 12:03 [#1]:Бубырь Александр Николаевич Если можно добавьте в ниже приведённую процедуру то что я хочу
 
 procedure tform1.bitbtntoexcelonclick(sender: tobject);
 var
 workbk : _workbook; // определяем workbook
 worksheet : _worksheet; // определяем worksheet
 i, j, k, r, c : integer;
 iindex : olevariant;
 tabgrid : variant;
 begin
 if genericstringgrid.cells[0,1] < > '' then
 begin
 iindex := 1;
 r := genericstringgrid.rowcount;
 c := genericstringgrid.colcount;
 // Создаём массив-матрицу
 tabgrid := vararraycreate([0,(r - 1),0,(c - 1)],varolestr);
 i := 0;
 // Определяем цикл для заполнения массива-матрицы
 repeat
 for j := 0 to (c - 1) do
 tabgrid[i,j] := genericstringgrid.cells[j,i];
 inc(i,1);
 until
 i > (r - 1);
 xlapp.connect;// Соединяемся с сервером texcelapplication
 // Добавляем workbooks в excelapplication
 xlapp.workbooks.add(xlwbatworksheet,0);
 // Выбираем первую workbook
 workbk := xlapp.workbooks.item[iindex];
 // Определяем первый worksheet
 worksheet := workbk.worksheets.get_item(1) as _worksheet;
 // Сопоставляем delphi массив-матрицу с матрицей в worksheet
 worksheet.range['a1',worksheet.cells.item[r,c]].value := tabgrid;
 // Заполняем свойства worksheet
 worksheet.name := 'customers';
 worksheet.columns.font.bold := true;
 worksheet.columns.horizontalalignment := xlright;
 worksheet.columns.columnwidth := 14;
 // Заполняем всю первую колонку
 worksheet.range['a' + inttostr(1),'a' + inttostr(r)].font.color := clblue;
 worksheet.range['a' + inttostr(1),'a' + inttostr(r)].horizontalalignment := xlhalignleft;
 worksheet.range['a' + inttostr(1),'a' + inttostr(r)].columnwidth := 31;
 
 {Здесь надо вставить столбец за первым и заполнить его значениями применив к первому столбцу формулу(не буду усложнять пусть будет +3600 к значениям первого столбца.У меня получилось что то вроде
 Columns("B:B").Select
 Selection.Insert Shift:=xlToRight
 Range("B2").Select
 ActiveCell.FormulaR1C1 = "=RC[-1]+3600"
 Range("B2").Select
 Selection.Copy
 Columns("B:B").Select
 ActiveSheet.Paste
 Application.CutCopyMode = False
 ActiveWorkbook.Save}
 
 xlapp.visible[0] := true;// Показываем excel
 xlapp.disconnect;// Разрываем связь с сервером
 tabgrid := unassigned;
 end;
 end;
 |  
|   | ANBsoft (статус: Студент), 19 июля 2008, 15:15 [#2]:Примерно так: 
 Var ExcelApp,Book,Sheet:Variant;
 begin
 ExcelApp:=CreateOleObject('Excel.Application');
 ExcelApp.Workbooks.Add[-4167{XLWBatWorksheet}];
 Book:=ExcelApp.Workbooks[1];
 Sheet:=Book.Worksheets[1];
 ExcelApp.Visible:=True;//Это можно поставить в конце - быстрее отработает, но если будет ошибка - Excel останется невидимым
 //  Sheet.Range[Sheet.Cells[Y1,X1],Sheet.Cells[Y2,X2]]:=tabgrid;
 sheet.name := 'customers';
 sheet.columns.font.bold := true;
 sheet.columns.horizontalalignment := -4152{xlright};
 sheet.columns.columnwidth := 14;
 
 sheet.columns[1].font.color := clblue;
 sheet.columns[1].horizontalalignment := -4131{xlhalignleft};
 sheet.columns[1].columnwidth := 31;
 
 sheet.cells[1,2].Select;
 ExcelApp.Selection.EntireColumn.Insert;
 Sheet.Range[Sheet.Cells[1,2],Sheet.Cells[10,2]]:='=RC[-1]+3600';
 |  
|   | ANBsoft (статус: Студент), 19 июля 2008, 15:17 [#3]:// Sheet.Range[Sheet.Cells[Y1,X1],Sheet.Cells[Y2,X2]]:=tabgrid; не выполнял, так как лень было данными заполнять, раскоментируйте и будет работать
 |  
|   | ANBsoft (статус: Студент), 19 июля 2008, 15:23 [#4]:Неохота разбираться, скорее всего TExcelApplication работает точно также через OLE. Просто когда мне это понадобилось в первый раз, это было очень давно, а в Делфи3 этих компонентов не было, а потом привык так делать, даже свои модули были готовы, только подключай и вызывай. |  
|   | Мережников Андрей (статус: Абитуриент), 19 июля 2008, 22:05 [#5]:Работа практически одинакова в обоих случаях. Отличие в том, что компонент TExcelApplication является компонентом VCL и, следовательно, требует обязательного наличия формы. Ну и то, что в первом случае необходимо самому заботиться о создании и уничтожении объекта. |  
|   | ANBsoft (статус: Студент), 20 июля 2008, 03:07 [#6]:Ну создать объект можно и без формы в рунтайме А в данном случае зачем его уничтожать, получаем отдельный экземпляр Excel с отчетом в нем, пользователь сам его закроет когда станет не нужен.
 В моем примере есть только три переменные, которые ссылаются на экземпляр Excel, они занимают по 16 байт.
 |  
|   | GAZ (статус: Посетитель), 20 июля 2008, 08:15 [#7]:Бубырь Александр Николаевич Если можно объясните по какому принципу назначаете значение const
 -4167,-4152,-4131,если есть какая то таблица где её посмотреть,почему именно '-' и четырёх значные.
 |  
|   | ANBsoft (статус: Студент), 20 июля 2008, 11:32 [#8]:Я заполнял эти значения по мере надобности. При записи макроса, Excel ставит в тексте эти константы,
 Для выяснения значения делаем макрос вида Cells(1,1)=xlhalignleft
 После выполнения в первой ячейке получаем значение этой константы.
 Вот значения некоторых, найденные в инете и вычисленные мной:
 const
 { XlSheetType }
 xlChart = -4109;
 xlDialogSheet = -4116;
 xlExcel4IntlMacroSheet = 4;
 xlExcel4MacroSheet = 3;
 xlWorksheet = -4167;
 
 { XlWBATemplate }
 xlWBATChart = -4109;
 xlWBATExcel4IntlMacroSheet = 4;
 xlWBATExcel4MacroSheet = 3;
 xlWBATWorksheet = -4167;
 
 { XlPattern }
 xlPatternAutomatic = -4105;
 xlPatternChecker = 9;
 xlPatternCrissCross = 16;
 xlPatternDown = -4121;
 xlPatternGray16 = 17;
 xlPatternGray25 = -4124;
 xlPatternGray50 = -4125;
 xlPatternGray75 = -4126;
 xlPatternGray8 = 18;
 xlPatternGrid = 15;
 xlPatternHorizontal = -4128;
 xlPatternLightDown = 13;
 xlPatternLightHorizontal = 11;
 xlPatternLightUp = 14;
 xlPatternLightVertical = 12;
 xlPatternNone = -4142;
 xlPatternSemiGray75 = 10;
 xlPatternSolid = 1;
 xlPatternUp = -4162;
 xlPatternVertical = -4166;
 
 { XlBordersIndex }
 xlInsideHorizontal = 12;
 xlInsideVertical = 11;
 xlDiagonalDown = 5;
 xlDiagonalUp = 6;
 xlEdgeBottom = 9;
 xlEdgeLeft = 7;
 xlEdgeRight = 10;
 xlEdgeTop = 8;
 
 { XlLineStyle }
 xlContinuous = 1;
 xlDash = -4115;
 xlDashDot = 4;
 xlDashDotDot = 5;
 xlDot = -4118;
 xlDouble = -4119;
 xlSlantDashDot = 13;
 xlLineStyleNone = -4142;
 
 { XlChartType }
 xlColumnClustered = 51;
 xlColumnStacked = 52;
 xlColumnStacked100 = 53;
 xl3DColumnClustered = 54;
 xl3DColumnStacked = 55;
 xl3DColumnStacked100 = 56;
 xlBarClustered = 57;
 xlBarStacked = 58;
 xlBarStacked100 = 59;
 xl3DBarClustered = 60;
 xl3DBarStacked = 61;
 xl3DBarStacked100 = 62;
 xlLineStacked = 63;
 xlLineStacked100 = 64;
 xlLineMarkers = 65;
 xlLineMarkersStacked = 66;
 xlLineMarkersStacked100 = 67;
 xlPieOfPie = 68;
 xlPieExploded = 69;
 xl3DPieExploded = 70;
 xlBarOfPie = 71;
 xlXYScatterSmooth = 72;
 xlXYScatterSmoothNoMarkers = 73;
 xlXYScatterLines = 74;
 xlXYScatterLinesNoMarkers = 75;
 xlAreaStacked = 76;
 xlAreaStacked100 = 77;
 xl3DAreaStacked = 78;
 xl3DAreaStacked100 = 79;
 xlDoughnutExploded = 80;
 xlRadarMarkers = 81;
 xlRadarFilled = 82;
 xlSurface = 83;
 xlSurfaceWireframe = 84;
 xlSurfaceTopView = 85;
 xlSurfaceTopViewWireframe = 86;
 xlBubble = 15;
 xlBubble3DEffect = 87;
 xlStockHLC = 88;
 xlStockOHLC = 89;
 xlStockVHLC = 90;
 xlStockVOHLC = 91;
 xlCylinderColClustered = 92;
 xlCylinderColStacked = 93;
 xlCylinderColStacked100 = 94;
 xlCylinderBarClustered = 95;
 xlCylinderBarStacked = 96;
 xlCylinderBarStacked100 = 97;
 xlCylinderCol = 98;
 xlConeColClustered = 99;
 xlConeColStacked = 100;
 xlConeColStacked100 = 101;
 xlConeBarClustered = 102;
 xlConeBarStacked = 103;
 xlConeBarStacked100 = 104;
 xlConeCol = 105;
 xlPyramidColClustered = 106;
 xlPyramidColStacked = 107;
 xlPyramidColStacked100 = 108;
 xlPyramidBarClustered = 109;
 xlPyramidBarStacked = 110;
 xlPyramidBarStacked100 = 111;
 xlPyramidCol = 112;
 xl3DColumn = -4100;
 xlLine = 4;
 xl3DLine = -4101;
 xl3DPie = -4102;
 xlPie = 5;
 xlXYScatter = -4169;
 xl3DArea = -4098;
 xlArea = 1;
 xlDoughnut = -4120;
 xlRadar = -4151;
 
 { Various Constants }
 xlAll = -4104;
 xlAutomatic = -4105;
 xlBoth = 1;
 xlCenter = -4108;
 xlChecker = 9;
 xlCircle = 8;
 xlCorner = 2;
 xlCrissCross = 16;
 xlCross = 4;
 xlDiamond = 2;
 xlDistributed = -4117;
 xlDoubleAccounting = 5;
 xlFixedValue = 1;
 xlFormats = -4122;
 xlGray16 = 17;
 xlGray8 = 18;
 xlGrid = 15;
 xlHigh = -4127;
 xlInside = 2;
 xlJustify = -4130;
 xlLightDown = 13;
 xlLightHorizontal = 11;
 xlLightUp = 14;
 xlLightVertical = 12;
 xlLow = -4134;
 xlManual = -4135;
 xlMinusValues = 3;
 xlModule = -4141;
 xlNextToAxis = 4;
 xlNone = -4142;
 xlNotes = -4144;
 xlOff = -4146;
 xlOn = 1;
 xlPercent = 2;
 xlPlus = 9;
 xlPlusValues = 2;
 xlSemiGray75 = 10;
 xlShowLabel = 4;
 xlShowLabelAndPercent = 5;
 xlShowPercent = 3;
 xlShowValue = 2;
 xlSimple = -4154;
 xlSingle = 2;
 xlSingleAccounting = 4;
 xlSolid = 1;
 xlSquare = 1;
 xlStar = 5;
 xlStError = 4;
 xlToolbarButton = 2;
 xlTriangle = 3;
 xlGray25 = -4124;
 xlGray50 = -4125;
 xlGray75 = -4126;
 xlBottom = -4107;
 xlLeft = -4131;
 xlRight = -4152;
 xlTop = -4160;
 xl3DBar = -4099;
 xl3DSurface = -4103;
 xlBar = 2;
 xlColumn = 3;
 xlCombination = -4111;
 xlCustom = -4114;
 xlDefaultAutoFormat = -1;
 xlMaximum = 2;
 xlMinimum = 4;
 xlOpaque = 3;
 xlTransparent = 2;
 xlBidi = -5000;
 xlLatin = -5001;
 xlContext = -5002;
 xlLTR = -5003;
 xlRTL = -5004;
 xlVisualCursor = 2;
 xlLogicalCursor = 1;
 xlSystem = 1;
 xlPartial = 3;
 xlHindiNumerals = 3;
 xlBidiCalendar = 3;
 xlGregorian = 2;
 xlComplete = 4;
 xlScale = 3;
 xlClosed = 3;
 xlColor1 = 7;
 xlColor2 = 8;
 xlColor3 = 9;
 xlConstants = 2;
 xlContents = 2;
 xlBelow = 1;
 xlCascade = 7;
 xlCenterAcrossSelection = 7;
 xlChart4 = 2;
 xlChartSeries = 17;
 xlChartShort = 6;
 xlChartTitles = 18;
 xlClassic1 = 1;
 xlClassic2 = 2;
 xlClassic3 = 3;
 xl3DEffects1 = 13;
 xl3DEffects2 = 14;
 xlAbove = 0;
 xlAccounting1 = 4;
 xlAccounting2 = 5;
 xlAccounting3 = 6;
 xlAccounting4 = 17;
 xlAdd = 2;
 xlDebugCodePane = 13;
 xlDesktop = 9;
 xlDirect = 1;
 xlDivide = 5;
 xlDoubleClosed = 5;
 xlDoubleOpen = 4;
 xlDoubleQuote = 1;
 xlEntireChart = 20;
 xlExcelMenus = 1;
 xlExtended = 3;
 xlFill = 5;
 xlFirst = 0;
 xlFloating = 5;
 xlFormula = 5;
 xlGeneral = 1;
 xlGridline = 22;
 xlIcons = 1;
 xlImmediatePane = 12;
 xlInteger = 2;
 xlLast = 1;
 xlLastCell = 11;
 xlList1 = 10;
 xlList2 = 11;
 xlList3 = 12;
 xlLocalFormat1 = 15;
 xlLocalFormat2 = 16;
 xlLong = 3;
 xlLotusHelp = 2;
 xlMacrosheetCell = 7;
 xlMixed = 2;
 xlMultiply = 4;
 xlNarrow = 1;
 xlNoDocuments = 3;
 xlOpen = 2;
 xlOutside = 3;
 xlReference = 4;
 xlSemiautomatic = 2;
 xlShort = 1;
 xlSingleQuote = 2;
 xlStrict = 2;
 xlSubtract = 3;
 xlTextBox = 16;
 xlTiled = 1;
 xlTitleBar = 8;
 xlToolbar = 1;
 xlVisible = 12;
 xlWatchPane = 11;
 xlWide = 3;
 xlWorkbookTab = 6;
 xlWorksheet4 = 1;
 xlWorksheetCell = 3;
 xlWorksheetShort = 5;
 xlAllExceptBorders = 6;
 xlLeftToRight = 2;
 xlTopToBottom = 1;
 xlVeryHidden = 2;
 xlDrawingObject = 14;
 xlUp = -4162;
 
 {ANB}
 xlRows = 1;
 xlCategory = 1;
 xlPrimary = 1;
 xlValue = 1;
 xlLocationAsObject = 2;
 xlWindows = 2;
 xlFixedWidth = 2;
 xlThick = 4;
 xlMedium = -4138;
 xlThin = 2;
 xlHairline = 1;
 xlLandscape = 2;
 xlPortrait = 1;
 xlToLeft = -4159;
 xlFillDefault=0;
 xlFillSeries=1;
 xlFillCopy=2;
 xlFillFormats=3;
 xlFillValues=4;
 xlFillDays=5;
 xlFillWeekdays=6;
 xlFillMonths=7;
 xlFillYears=8;
 xlLinearTrend=9;
 xlGrowthTrend=10;
 xlDatabase=1;
 xlDataField=4;
 xlSum=-4157;
 xlUnderlineStyleSingle=2;
 xlCellValue=1;
 xlExpression=2;
 xlBetween=1;
 xlNotBetween=2;
 xlEqual=3;
 xlNotEqual=4;
 xlGreater=5;
 xlLess=6;
 xlGreaterEqual=7;
 xlLessEqual=8;
 xlAscending=1;
 xlGuess=0;
 |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |