Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Population an Excel Range with an array
Message
De
07/07/2013 10:35:41
Charlie Schreiner
Myers and Stauffer Consulting
Topeka, Kansas, États-Unis
 
 
À
06/07/2013 17:31:05
Information générale
Forum:
Visual FoxPro
Catégorie:
COM/DCOM et OLE Automation
Versions des environnements
Visual FoxPro:
VFP 9 SP2
OS:
Windows Server 2012
Network:
Windows 2008 Server
Database:
MS SQL Server
Application:
Web
Divers
Thread ID:
01577886
Message ID:
01577918
Vues:
51
We use the array copy method, and we have had to add an ArrayInterator, or perhaps better named MaxRows4Array property. It's set at 50,000 currently and that seems to be working well.
PARAMETERS Row, Column, DataArray
LOCAL RowCnt, ColCnt, EleCnt, CurRowCnt, EleStart

&& LPARAM cannot be used because DataArray needs to be here as a private variable, not local
&& You can use SELECT * INTO ARRAY aName to build the array
&& Example: 
&& LOCAL ARRAY aTmp[1]
&& SELECT * FROM (oDR.Alias) INTO ARRAY aTmp
&& This.PasteArrayAtCell(1,1, @aTmp)

LOCAL oRng AS Object
WITH This
   RowCnt = ALEN(DataArray, 1)
   ColCnt = MAX(ALEN(DataArray, 2),1)
   IF m.RowCnt > .ArrayIterator
      && loop through paste to avoid data errors with memory
      && initial seed
      CurRow = 1
      CurRowCnt = .ArrayIterator
      DO WHILE m.CurRow <= m.RowCnt
         EleStart = ((m.currow - 1) * m.colcnt) + 1
         EleCnt = m.CurRowCnt * m.ColCnt
         DIMENSION DataCopy[m.CurRowCnt, m.ColCnt] && pre-dimension, otherwise whole array is copied with empty elements
         ACOPY(DataArray, DataCopy, m.EleStart, m.EleCnt)
         oRng = .GetCell(m.Row + m.CurRow - 1, m.Column)
         oRng = oRng.Resize(m.CurRowCnt, m.ColCnt)
         oRng.Value = .aPasser('DataCopy')
         CurRow = m.CurRow + m.CurRowCnt
         CurRowCnt = MIN(m.RowCnt - m.CurRow + 1, .ArrayIterator)
      ENDDO
   ELSE
      oRng = .GetCell(m.Row, m.Column)
      oRng = oRng.Resize(m.RowCnt, m.ColCnt)
      oRng.Value = .aPasser('DataArray')
   ENDIF
ENDWITH
>For everyone's information:
>Filling a 4 column worksheet with 2500 rows from a dbf one cell at a time takes about 3 seconds on a pretty fast machine. That was a problem for me since the app in question might have a lot more volume than that at times and that's why I started looking around.
>Using the array method with the same data, it's instantaneous.
>Further, MS advises that the Excel interop engine has a 64K space for range references and since each cell fill uses a new range reference, filling a speadsheet with high volumes of data a cell at a time might destabilize the engine.
>No such problem with the array method
>
>
>
>
>>Check Message ID: 1076673
>>
>>>Populating Excel rows from a table one at a time can be very slow.
>>>I came across something in .NET that speeds the process up a lot.. you can populate a range of cells from an array
>>>
>>>Using the .NET code below, I get a spreadsheet with the names where the belong.
>>>Using the VFP code below it, I get the word "John" in every cell.
>>>Can anyone tell me how to get it to see the whole array?
>>>
>>>Thanks in advance!!
>>>
>>>
>>>
>>>// .NET Code
>>>using System;
>>>using Excel = Microsoft.Office.Interop.Excel;
>>>using System.Reflection; 
>>>
>>>using System.Collections.Generic;
>>>using System.Linq;
>>>using System.Windows.Forms;
>>>using System.Text;
>>>
>>>namespace ExcelArray
>>>{
>>>  class Program
>>>  {
>>>    
>>>
>>>
>>>
>>>    static void Main(string[] args)
>>>    {
>>>      Excel.Application oXL;
>>>      Excel._Workbook oWB;
>>>      Excel._Worksheet oSheet;
>>>      Excel.Range oRng;
>>>      try
>>>      {
>>>        //Start Excel and get Application object.
>>>        oXL = new Excel.Application();
>>>        oXL.Visible = true;
>>>
>>>        //Get a new workbook.
>>>        oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value));
>>>        oSheet = (Excel._Worksheet)oWB.ActiveSheet;
>>>
>>>        //Add table headers going cell by cell.
>>>        oSheet.Cells[1, 1] = "First Name";
>>>        oSheet.Cells[1, 2] = "Last Name";
>>>        oSheet.Cells[1, 3] = "Full Name";
>>>        oSheet.Cells[1, 4] = "Salary";
>>>
>>>        //Format A1:D1 as bold, vertical alignment = center.
>>>        oSheet.get_Range("A1", "D1").Font.Bold = true;
>>>        oSheet.get_Range("A1", "D1").VerticalAlignment =
>>>          Excel.XlVAlign.xlVAlignCenter;
>>>
>>>        // Create an array to multiple values at once.
>>>        string[,] saNames = new string[5, 2];
>>>
>>>        saNames[0, 0] = "John";
>>>        saNames[0, 1] = "Smith";
>>>        saNames[1, 0] = "Tom";
>>>        saNames[1, 1] = "Brown";
>>>        saNames[2, 0] = "Sue";
>>>        saNames[2, 1] = "Thomas";
>>>        saNames[3, 0] = "Jane";
>>>        saNames[3, 1] = "Jones";
>>>        saNames[4, 0] = "Adam";
>>>        saNames[4, 1] = "Johnson";
>>>
>>>        //Fill A2:B6 with an array of values (First and Last Names).
>>>        oSheet.get_Range("A2", "B6").Value2 = saNames;
>>>
>>>        //Fill C2:C6 with a relative formula (=A2 & " " & B2).
>>>        oRng = oSheet.get_Range("C2", "C6");
>>>        oRng.Formula = "=A2 & \" \" & B2";
>>>
>>>        //Fill D2:D6 with a formula(=RAND()*100000) and apply format.
>>>        oRng = oSheet.get_Range("D2", "D6");
>>>        oRng.Formula = "=RAND()*100000";
>>>        oRng.NumberFormat = "$0.00";
>>>
>>>        //AutoFit columns A:D.
>>>        oRng = oSheet.get_Range("A1", "D1");
>>>        oRng.EntireColumn.AutoFit();
>>>
>>>        //Manipulate a variable number of columns for Quarterly Sales Data.
>>>      //  DisplayQuarterlySales(oSheet);
>>>
>>>        //Make sure Excel is visible and give the user control
>>>        //of Microsoft Excel's lifetime.
>>>        oXL.Visible = true;
>>>        oXL.UserControl = true;
>>>      }
>>>      catch (Exception theException)
>>>      {
>>>        String errorMessage;
>>>        errorMessage = "Error: ";
>>>        errorMessage = String.Concat(errorMessage, theException.Message);
>>>        errorMessage = String.Concat(errorMessage, " Line: ");
>>>        errorMessage = String.Concat(errorMessage, theException.Source);
>>>
>>>        MessageBox.Show(errorMessage, "Error");
>>>      }
>>>
>>>
>>>    }
>>>  }
>>>}
>>>
>>>
>>>
>>>
>>>*-- VFP Code
>>>CLOSE ALL
>>>CLEAR ALL
>>>DIMENSION saNames(5,2)
>>>saNames[1, 1] = "John"
>>>saNames[1, 2] = "Smith"
>>>saNames[2, 1] = "Tom"
>>>saNames[2, 2] = "Brown"
>>>saNames[3, 1] = "Sue"
>>>saNames[3, 2] = "Thomas"
>>>saNames[4, 1] = "Jane"
>>>saNames[4, 2] = "Jones"
>>>saNames[5, 1] = "Adam"
>>>saNames[5, 2] = "Johnson"
>>>oExcel = CREATEOBJECT("Excel.Application")
>>>oExcel.Visible = .T.
>>>oBook =  oExcel.Workbooks.Add()
>>>oBook.Sheets[1].Name = "Summary"
>>>
>>>WITH oExcel.ActiveSheet
>>>  .Range["A1"].Value = "First"
>>>  .Range["B1"].Value = "Last"
>>>  oRange = .Range["A2:B6"]
>>>ENDWITH
>>>oRange.Value2 = saNames
>>>
>>>
Charlie
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform