2016-07-25 3 views
0

Это их любая команда в Foxpro, которая преобразует DBF в конкретный лист excel. У меня есть три DBF (dbf_1, dbf_2, dbf_3). Моя текущая программа конвертирует файл с использованием кода в «filename.xls» типа fox2x, а затем вручную скопирую консолидированный лист в одно превосходное. Для меня этот метод, который я использую, в порядке, но что, если их 20 или более dbf, которые я буду консолидировать. Их любая команда в foxpro преобразует dbf в один файл excel. Я уже использую foxpro Automation, но он должен замедляться.COPY TO excel Sheet in foxpro

ответ

3

Нет, нет.

Также "копировать ... тип fox2x". хотя лучше, чем многие другие варианты (например, csv и xls) не следует выбирать, когда есть лучшие способы.

Вы говорите, что автоматизация работает медленно, но не знаю, если вы на самом деле находите автоматизацию медленной, или если вы пробовали ее так, как вы не должны использовать для передачи данных в Excel. В приведенном ниже примере используйте один из вариантов моей функции «vfp2excel» и автоматизации. Он передает образцы данных Customer, Employee, Orders, OrdItems и Products за 2,5 секунды на моей машине. Если вы на самом деле не имел в виду это, как медленно потом не кости, иначе здесь образец:

* These represent complex SQL as a sample 
Select emp_id,First_Name,Last_Name,; 
    Title,Notes ; 
    from (_samples+'\data\employee') ; 
    into Cursor crsEmployee ; 
    readwrite 
Replace All Notes With Chrtran(Notes,Chr(13)+Chr(10),Chr(10)) 

Select cust_id,company,contact,Title,country,postalcode ; 
    from (_samples+'\data\customer') ; 
    into Cursor crsCustomer ; 
    nofilter 

Select * ; 
    from (_samples+'\data\orders') ; 
    into Cursor crsOrders ; 
    nofilter 

Select * ; 
    from (_samples+'\data\orditems') ; 
    into Cursor crsOrderDetail ; 
    nofilter 

Select * ; 
    from (_samples+'\data\products') ; 
    into Cursor crsProducts ; 
    nofilter 

* Now we want to get these on 3 sheets 
* Sheet1: Employees only 
* Sheet2: Customers only 
* Sheet3: Orders, ordItems, Products layed out horizontally 

Local oExcel 
oExcel = Createobject("Excel.Application") 
With oExcel 
    .DisplayAlerts = .F. 
    .Workbooks.Add 
    .Visible = .T. 
    With .ActiveWorkBook 
     For ix = 1 To 3 && We want 3 Sheets 
      If .sheets.Count < m.ix 
       .sheets.Add(,.sheets(.sheets.Count)) && Add new sheets 
      Endif 
     Endfor 
     * Name the sheets 
     .WorkSheets(1).Name = "Employees" 
     .WorkSheets(2).Name = "Customers" 
     .WorkSheets(3).Name = "Order, OrderDetail, Products" && max sheetname is 31 chars 

     * Start sending data 
     * First one has headers specified 
     VFP2Excel('crsEmployee', .WorkSheets(1).Range("A1"), ; 
      "Id,First Name,Last Name,Employee Title,Comments about employee") && To sheet1, start at A1 
     VFP2Excel('crsCustomer', .WorkSheets(2).Range("A1")) && To sheet2, start at A1 
     VFP2Excel('crsOrders',  .WorkSheets(3).Range("A1")) && To sheet3, start at A1 
     * Need to know where to put next 
     * Leave 2 columns empty - something like 'G1' 
     lcRange = _GetChar(.WorkSheets(3).UsedRange.Columns.Count + 3) + '1' 
     * To sheet3, start at next to previous 
     VFP2Excel('crsOrderDetail', .WorkSheets(3).Range(m.lcRange)) 

     lcRange = _GetChar(.WorkSheets(3).UsedRange.Columns.Count + 3) + '1' 
     * To sheet3, start at next to previous 
     VFP2Excel('crsProducts', .WorkSheets(3).Range(m.lcRange)) 

     #Define xlJustify           -4130 
     #Define xlTop            -4160 

     * I just happen to know notes in at column 5 from SQL 
     * No need to query from excel to keep code simple 
     * Lets format that column specially instead of leaving 
     * at the mercy of Excel's autofitting 
     .WorkSheets(1).UsedRange.VerticalAlignment = xlTop && set all to top 
     With .WorkSheets(1).Columns(5) 
      .ColumnWidth = 80 && 80 chars width 
      .WrapText = .T. 
      *  .HorizontalAlignment = xlJustify && doesn't work good always 
     Endwith 

     * Finally some cosmetic stuff 
     For ix=1 To 3 
      With .WorkSheets(m.ix) 
       .Columns.AutoFit 
       .Rows.AutoFit 
      Endwith 
     Endfor 

     .WorkSheets(1).Activate 
    Endwith 
Endwith 


* Author: Cetin Basoz 
* This is based on earlier VFP2Excel function codes 
* that has been published on the internet, at various sites 
* since 2001. Not to be messed with others' code who named the same but has 
* nothing to do with the approaches taken here (unless copy & pasted and claimed 
* to be their own work, <s> that happens). 
Procedure VFP2Excel(tcCursorName, toRange, tcHeaders, tnPrefferredWidthForMemo) 
    * tcCursorName 
    * toRange 
    * tcHeaders: Optional. Defaults to field headers 
    * tnPrefferredWidthForMemo: Optional. Default 80 
    * Function VFP2Excel 
    tcCursorName = Evl(m.tcCursorName,Alias()) 
    tnPrefferredWidthForMemo = Evl(m.tnPrefferredWidthForMemo,80) 
    Local loConn As AdoDB.Connection, loRS As AdoDB.Recordset,; 
     lcTemp,lcTempDb, oExcel,ix, lcFieldName, lcHeaders 

    lnSelect = Select() 
    lcTemp = Forcepath(Sys(2015)+'.dbf',Sys(2023)) 
    lcTempDb = Forcepath(Sys(2015)+'.dbc',Sys(2023)) 

    Create Database (m.lcTempDb) 
    Select * From (m.tcCursorName) Into Table (m.lcTemp) Database (m.lcTempDb) 

    Local Array aMemo[1] 
    Local nMemoCount 
    nMemoCount = 0 
    lcHeaders = '' 
    For ix = 1 To Fcount() 
     lcFieldName = Field(m.ix) 
     If Type(Field(m.ix))='M' 
      nMemoCount = m.nMemoCount + 1 
      Dimension aMemo[m.nMemoCount] 
      aMemo[m.nMemoCount] = m.ix 
      Replace All &lcFieldName With Chrtran(&lcFieldName,Chr(13)+Chr(10),Chr(10)) 
     Endif 
     lcHeaders = m.lcHeaders + Iif(Empty(m.lcHeaders),'',',')+Proper(m.lcFieldName) 
    Endfor 
    tcHeaders = Evl(m.tcHeaders,m.lcHeaders) 

    Use In (Juststem(m.lcTemp)) 
    Close Databases 
    Set Database To 

    loStream = Createobject('AdoDb.Stream') 
    loConn = Createobject('ADODB.Connection') 
    loRS = Createobject("ADODB.Recordset") 
    loConn.ConnectionString = "Provider=VFPOLEDB;Data Source="+m.lcTempDb 
    loConn.Open() 
    loRS = loConn.Execute("select * from "+m.lcTemp) 
    loRS.Save(loStream) 
    loRS.Close 
    loConn.Close 
    Erase (m.lcTemp) 

    * Use first row for headers 
    Local Array aHeader[1] 

    loRS.Open(loStream) 
    toRange.Offset(1,0).CopyFromRecordSet(loRS) && Copy data starting from headerrow + 1 

    Set Safety Off 
    Delete Database (m.lcTempDb) Deletetables 

    Select (m.lnSelect) 

    For ix=1 To Iif(!Empty(m.tcHeaders), ; 
      ALINES(aHeader, m.tcHeaders,1,','), ; 
      loRS.Fields.Count) 
     toRange.Offset(0,m.ix-1).Value = ; 
      Iif(!Empty(m.tcHeaders), ; 
      aHeader[m.ix], ; 
      Proper(loRS.Fields(m.ix-1).Name)) 
     toRange.Offset(0,m.ix-1).Font.Bold = .T. 
    Endfor 

    #Define xlJustify           -4130 
    #Define xlTop            -4160 
    * This part is cosmetic 
    toRange.WorkSheet.Activate 
    With toRange.WorkSheet.UsedRange 
     .VerticalAlignment = xlTop && set all to top 
     For ix=1 To m.nMemoCount 
      With .Columns(aMemo[m.ix]) 
       .ColumnWidth = m.tnPrefferredWidthForMemo && 80 chars width 
       .WrapText = .T. 
      Endwith 
     Endfor 
     .Columns.AutoFit 
     .Rows.AutoFit 
    Endwith 
Endproc 

* Return A, AA, BC etc noation for nth column 
Function _GetChar 
    Lparameters tnColumn && Convert tnvalue to Excel alpha notation 
    If m.tnColumn = 0 
     Return "" 
    Endif 
    If m.tnColumn <= 26 
     Return Chr(Asc("A")-1+m.tnColumn) 
    Else 
     Return _GetChar(Int(Iif(m.tnColumn % 26 = 0,m.tnColumn - 1, m.tnColumn)/26)) + ; 
      _GetChar((m.tnColumn-1)%26+1) 
    Endif 
Endfunc 
+0

Благодарим за помощь.Моя проблема в Foxpro Automation заключается в том, что в моем отчете превосходно, что многие формулы включены, почему они очень медленные. Сейчас я размышляю о том, как скопировать определенный лист в Foxpro Automation, чтобы после переноса данных в excel я скопировал листы с формулой на рабочие листы. – Vic

+0

Я думаю, вы не читали код. Вы можете сохранить лист (ы) с формулой в качестве шаблона и добавить новую книгу excel на основе этого шаблона или написать формулу для нескольких ячеек сразу. Или требуется только одна команда для копирования листов в книгу из другой. –

0

Это то, что я искал :-) Я пытался с моим знанием Excel автоматизации программирования в Visual FoxPro, но всегда получал ошибки. Моя задача состояла в том, чтобы создать «n» Таблицы из одного большого курсора, который я хочу проанализировать относительно выбора пользователем имени атрибута из курсора, чтобы получить также «n» Таблицы. Этот образец предназначен для 3 курсоров и 3 листов и является общим. Но мне это нужно для «п» курсоры и один атрибут который клиент выбрать к отчетливой и получить «п» Листы в одном Excel файл. Итак, теперь у меня есть динамическая процедура. Я настроил этот код и решил свою проблему, которую я пытаюсь закончить около 4 дней. Так что еще раз спасибо за этот код, и, конечно же, я не буду изменять процедуру VFP2Excel и написал где-то еще мое имя. Спасибо за помощь !

0

Там нет родной функции VFP, чтобы сделать это, НО, есть удивительный источник открытого проект, который имеет класс, который будет сделать это очень просто:

VFPx Workbook XLSX (см здесь) : https://vfpx.codeplex.com/wikipage?title=XLSXWorkbook

Он имеет 3 магические функции, которые будут делать то, что вы просили:

  • CreateWorkbook()
  • AddSheet()
  • SaveTableToWorkbook()

(Повтор команды 2 и 3 выше, для каждого DBF/листа вы хотите создать)

Это хорошо документированной с 54-страничный PDF и код образец, который объясняет все, что вам нужно знать.