Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Esportare in EXCEL non con TransferSpreadSheet

141 views
Skip to first unread message

Motel

unread,
Feb 23, 2012, 7:02:08 PM2/23/12
to
Ciao
esportando in excel da tabella access con il comando TransferSpreadSheet, succede che il file excel viene "ricoperto" dai nuovi dati.

Vorrei, invece, avere la possibillità di accodarli ad eventuali dati già esistenti (i formati sono identici) o di gestire la creazione di un nuovo foglio, con i nuovi dati; il tutto senza dover gestire manualmente riga per riga il foglio excel, ma continuando ad effettuare uno scarico massivo.

spero di essermi spiegato bene

Motel

BFS

unread,
Feb 24, 2012, 2:26:47 AM2/24/12
to
crea un pulsante "esporta" con questo codice

Dim objExcel As Object
Dim objWorkbook As Object
Dim db As Database
Set db = CurrentDb

Dim tuatab As DAO.Recordset
Set tuatab = db.OpenRecordset("NomeTuaTabella")

On Error Resume Next
Set objExcel = GetObject(, "Excel.Application")
If Err.Number Then
Err.Clear
Set objExcel = CreateObject("Excel.Application")
If Err.Number Then
MsgBox "Can't open Excel."
End If
End If
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Add


Call objExcel.range("A4").CopyFromRecordset(tuatab)

objExcel.Visible = True


ovviamente puoi parametrizzare la posizione dove incollare...nel mio
esempio la cella "A4"
magari creati nella stessa form una text dove digitare la cella di partenza

ciao
BFS

Red Wolf

unread,
Feb 24, 2012, 5:41:22 AM2/24/12
to
Il 24/02/2012 8.26, BFS ha scritto:
> iamente puoi parametrizzare la posi

anzitutto grazie

il problema è che non so sino dove è riempito il foglio excel...

BFS

unread,
Feb 24, 2012, 5:49:54 AM2/24/12
to
se il foglio excel è sempre e solo popolato dagli accodamenti che fai
non è difficile sapere a che riga sei.

se inizi dalla cella A1 e la tua tabella ha 50 record, la volta dopo
dovrai partire da A51
ti basta memorizzare in una tabella il valore della prima cella
disponibile per l'accodamento
e dopo l'accodamento aggiornare questo valore con
nuovovalore=vecchiovalore+n° record tuatabella

ciao
BFS

Red Wolf

unread,
Feb 24, 2012, 6:12:32 AM2/24/12
to
CUT
> e dopo l'accodamento aggiornare questo valore con
> nuovovalore=vecchiovalore+n° record tuatabella
>

purtroppo no
potrebbero aver cancellato alcuni record (o tutti) o ADDIRITTURA agginti
altri...
corretto o meno che sia quello che fanno devvo potergli far scegliere se
aggiornare il file o ricoprirlo del tutto o CREARLO ex novo.

non vorrei dover cominciare a contare le righe piene... se sono 5-6-7000
o più sai che perdita di tempo...

Popi - TheBadHabits

unread,
Feb 24, 2012, 5:51:55 AM2/24/12
to
Ciao!

La proprietà UsedRange ti è d'aiuto ;)

HTH
Popi

Red Wolf

unread,
Feb 24, 2012, 6:40:37 AM2/24/12
to
non conoscevo
provo

grazie

Bruno Campanini

unread,
Feb 24, 2012, 5:58:21 PM2/24/12
to
on 24-02-12, Motel supposed :
==========================================
Private Sub Command2_Click()
Dim xlApp As Object, xlSheet As Object, db As Database
Dim RS As Recordset, ExcelTargetRange As Object, FieldNum As Integer
Dim i As Long, j As Long, k As Long, TableName As String
Dim ExcelFileName As String, ExcelSheetName As String
Dim ExcelStartCell As String
'
' Definizioni
' ------------------------------
TableName = "T4"
FieldNum = 4
ExcelFileName = "C:\BC.xlsx"
ExcelSheetName = "Sheet1"
ExcelStartCell = "B5"
' ------------------------------
'
Set db = CurrentDb
Set RS = db.OpenRecordset(TableName, dbOpenDynaset)

Set xlApp = CreateObject("Excel.Application")
Set xlSheet = xlApp.Workbooks.Open(ExcelFileName)
Set ExcelTargetRange =
xlSheet.Sheets(ExcelSheetName).Range(ExcelStartCell)
'xlApp.Visible = True

Do
k = k + 1
If IsEmpty(ExcelTargetRange(k, 1)) Then
Exit Do
End If
Loop

Do Until RS.EOF
For i = 1 To FieldNum
ExcelTargetRange(k, i) = RS.Fields(i - 1)
Next
k = k + 1
RS.MoveNext
Loop
xlSheet.Close SaveChanges:=True

End Sub
=============================================

Bruno


@Alex

unread,
Feb 26, 2012, 6:46:27 AM2/26/12
to
Personalmente ho effettuato diversi test di efficienza sull'export in
Excel in seguito ad un'esigenza che mi richiedeva l'esportazione di
più di 1milione di Records...

Il sistema più veloce ed efficiente è il CopyFromRecordset di cui ti
allego esempio:

Function EXP2XLS(SQL as string, _
Optional ByRef NomeFile As String = vbNullString, _
Optional OpenDialog As Boolean = False, _
Optional CloseExcel As Boolean = True) As Boolean
On Error GoTo Handle_err
Dim xlApp As Object ' Oggetto EXCEL
Dim oWkb As Object ' Oggetto WORKBOOK

Dim x As Integer
Dim rs As DAO.Recordset

EXP2XLS= False

' APRE SE ESISTE GIA' UN'OGGETTO EXCEL
Set xlApp = CreateObject("Excel.Application")

Set oWkb = xlApp.Workbooks.Add()

If OpenDialog = True Then

Do Until NomeFile <> ""
NomeFile = xlApp.GetSaveAsFilename(InitialFilename:="C:
\TestExport.xls", _
fileFilter:="Excel
Files (*.xls), *.xls", _
Title:="SELEZIONA NOME
FILE")

DoEvents
Loop

End If

If Len(NomeFile) = 0 Then NomeFile = "C:\TestExport.xls"

If EsisteFile(NomeFile) Then Kill NomeFile

' ATTENZIONE ALLA VERSIONE DI EXCEL, usare 43 oppure 50 a seconda
della versione 2003 o superiore...
oWkb.SaveAs NomeFile, 43

' Elimino i Fogli che Excel crea di DEFAULT
For x = oWkb.Sheets.Count To 2 Step -1
oWkb.Sheets(x).Delete
Next

' Assegno un nome al Foglio(Sheet) rimasto.
oWkb.Sheets(1).Name = "MANUTENZIONI"

Set rs = CurrentDb.OpenRecordset(SQL,dbOpenDynaset,dbReadOnly)

' Scrivo nella Cella A1
oWkb.Sheets(1).Range("A1").CopyFromRecordset rs

rs.Close
Set rs = Nothing

EXP2XLS= True

Exit_Here:
oWkb.Save
If CloseExcel Then
oWkb.Close True
xlApp.Quit
Else
xlApp.Visible = True
End If
Set oWkb = Nothing
Set xlApp = Nothing
Exit Function

Handle_err:
MsgBox Err.Number & " " & Err.Description
Resume Exit_Here
End Function

Saluti
@Alex

Bruno Campanini

unread,
Feb 26, 2012, 7:09:37 AM2/26/12
to
@Alex explained :
> On 24 Feb, 01:02, Motel <diaz1...@virgilio.it> wrote:
>> Ciao
>> esportando in excel da tabella access con il comando TransferSpreadSheet,
>> succede che il file excel viene "ricoperto" dai nuovi dati.
>>
>> Vorrei, invece, avere la possibillità di accodarli ad eventuali dati già
>> esistenti (i formati sono identici) o di gestire la creazione di un nuovo
>> foglio, con i nuovi dati; il tutto senza dover gestire manualmente riga per
>> riga il foglio excel, ma continuando ad effettuare uno scarico massivo.
>>
>> spero di essermi spiegato bene
>>
>> Motel
>
> Personalmente ho effettuato diversi test di efficienza sull'export in
> Excel in seguito ad un'esigenza che mi richiedeva l'esportazione di
> più di 1milione di Records...
>
> Il sistema più veloce ed efficiente è il CopyFromRecordset di cui ti
> allego esempio:
[...]

Sì in effetti questo è vero sempre che si debba trasferire l'intero
recordset.
Nel mio codice basta sostituire la sezione Do... Loop con:
Call ExcelTargetRange(k, 1).CopyFromRecordset(RS)
(il Call è tassativo!)

Si perde però la possibilità di definire quali e quanti campi del
recordset si vogliono trasferire, quando non si vogliano trasferire
tutti.

Bruno


@Alex

unread,
Feb 26, 2012, 12:42:55 PM2/26/12
to
Ti mostro come si può definire in modo banale i campi da esportare...
anche in modo visuale, io lho risolto così:
http://forum.masterdrive.it/access-79/access-definire-i-campi-esportare-in-excel-54294/

ciao
@Alex

Bruno Campanini

unread,
Feb 26, 2012, 6:29:02 PM2/26/12
to
@Alex submitted this idea :

> Ti mostro come si può definire in modo banale i campi da esportare...
> anche in modo visuale, io lho risolto così:
> http://forum.masterdrive.it/access-79/access-definire-i-campi-esportare-in-excel-54294/

Sì ho capito.
Filtri prima attraverso una query poi su tutto il recordset così
filtrato esegui .CopyFromRecordset.

Io normalmente creo un array coi nomi (o gli ordinali) dei campi della
tabella che voglio trasferire.

Poi eseguo:
ExcelTargetRange(k, i) = RS.Fields(FieldArray(i))
all'interno di un For... Next.

E ci sarà ancora qualche altra decina di modi per eseguire
l'operazione.

Bruno


@Alex

unread,
Feb 27, 2012, 12:17:57 PM2/27/12
to
On 27 Feb, 00:29, Bruno Campanini <bruno...@libero.it> wrote:
> @Alex submitted this idea :
>
> > Ti mostro come si può definire in modo banale i campi da esportare...
> > anche in modo visuale, io lho risolto così:
> >http://forum.masterdrive.it/access-79/access-definire-i-campi-esporta...
>
> Sì ho capito.
> Filtri prima attraverso una query poi su tutto il recordset così
> filtrato esegui .CopyFromRecordset.
>
> Io normalmente creo un array coi nomi (o gli ordinali) dei campi della
> tabella che voglio trasferire.
>
> Poi eseguo:
>       ExcelTargetRange(k, i) = RS.Fields(FieldArray(i))
> all'interno di un For... Next.
>
> E ci sarà ancora qualche altra decina di modi per eseguire
> l'operazione.
>
> Bruno

Prova la differenza delle 2 tecniche con tabelle molto grosse....

Io ci ho perso qualche settimana per trovare il metodo più
performante, dovendo esportare qualche MILIONE di records per un
centinaio di Colonne..., ma magari c'è qualche metodo migliore...

Su quantità di dati attorno ad una decina di migliaia non ci sono
sostanziali differenze.

@Alex
0 new messages