Newsgroup: it.comp.lang.visual-basic
Titolo: Excel lanciato da servizio (VB.NET o VB6)

Ciao a tutti,
dovrei creare un file di excel da un servizio (vb6 o 
vb.net
).
Ho notato che anche con questo piccolo codice da task manager viene
generato un errore con l'eseguibile DW20.exe
Sbaglio qualcosa?
Grazie
| Public Class Service1
|     Protected Overrides Sub OnStart(ByVal args() As String)
|         Dim exclApp As Object, WBK As Object, WKS As Object
| 
|         exclApp = CreateObject("Excel.Application")
|         WBK = exclApp.Workbooks.Add
|         WKS = WBK.Worksheets.Add
|         WKS.Cells(1, 1).Value = "Ora: " & CStr(Now)
|         WKS.SaveAs("C:\test.xls")
| 
|     End Sub
| 
|     Protected Overrides Sub OnStop()
| 
|     End Sub
| End Class

"Andrea [Work]" <andrea.isw...@gmail.invalid> wrote in 
news:1n24i9m3knkg9$.
21cdpgf9...@40tude.net
:

secondo me sbagli a voler lanciare excel come servizio; non e' un software 
pensato per essere usato in quel modo (come gli altri applicativi del 
pacchetto office).
magari parte ma l'avvio s'intoppa, come pare succeda in questo caso, 
perche' tentano di partire anche altri software accessori con cui l'utente 
solitamente interagisce.
se devi solo creare un file xls, usa strade che non richiedano l'avvio di 
excel.
un esempio:
http://community.visual-basic.it/lucianob/archive/2005/07/15/15254.aspx
-- 
Paolo opg
BE AWARE that this post uses a fake reply-to address
to contact me write to:
janickg ( at ) hotmail ( dot ) com
--

 
http://community.visual-basic.it/lucianob/archive/2005/07/15/15254.aspx
Avrei delle procedure un po' piů complesse, da riportare come servizio
(aggiornare periodicamente dei file xls senza che ci sia un utente
loggato).
Si parla di mettere filtri, dare stili e formattazioni, fare grafici e
formule.
Sai se c'č qualche strada che mi permetterebbe di fare questo da servizio?
grazie

 Sai se c'è qualche strada che mi permetterebbe di fare questo da servizio?
OpenXml SDK, usi il nuovo formato di Office 2010 e vivi felicissimo :-)
Per le versioni vecchi c''è un plugin per office che ti permette di 
manipolare il nuovo formato senza il benché minimo problema.
.m
-- 
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com/profile/mauro
blog @ 
http://milestone.topics.it
whynot [ at ] topics [ dot ] it

 manipolare il nuovo formato senza il benché minimo problema.
Intendi il plugin per aprire xlsx, docx da installare sui client?
Oppure qualcosa che posso fare io nella creazione del file?

 Intendi il plugin per aprire xlsx, docx da installare sui client?
per aprire il file poi sul client.


 per aprire il file poi sul client.
Capito, oramai dovrebbero averlo molti clienti.
Grazie.

"Andrea [Work]" <andrea.isw...@gmail.invalid> wrote in
news:j3xx7d6skw2h$.
ul01p7tl...@40tude.net
: 

non ti so dare indicazioni perche' io per diverse ragioni evito 
accuratamente di usare excel per elaborazioni schedulate o comunque non 
fatte manualmente dagli utenti.
non so se hai dei vincoli per cui sei costretto a usare excel, ma al tuo 
posto importerei i dati in un rdbms, li elaborerei sul server e preparerei 
i report (i tuoi fogli excel sono dei report?) solo on demand.
visto poi che di solito i motori tipo reporting services di microsoft ti 
permettono di esportare nel formato che preferisci, gli utenti avrebbero 
comunque il loro bel foglietto di excel da pasticciare.


 Interessante, immagino non sia utilizzabile in VB6 vero?
Per VB6 puoi utilizzare il "vecchio" excel 2003 XML.
Ti incollo una funzione che noi utilizziamo su vecchi moduli VB6.
Gli passi un recordset, un nome file e un boolean che ti indica se va
scritta una testata o no e lei ti scrive un excel.
Public Function ExportToExcel(ByRef rs As Recordset, ByVal filename As
String, ByVal Testata As Boolean) As String
    On Error GoTo err
    Dim rowCount As Long
    Dim sheetcount As Integer
    Dim startExcelXML As String
    startExcelXML = "<?xml version=""1.0""?>" & vbCrLf & _
            "<?mso-application progid=""Excel.Sheet""?>" & vbCrLf & _
            "<Workbook " &
"xmlns=""urn:schemas-microsoft-com:office:spreadsheet""" & vbCrLf & _
            " xmlns:o=""urn:schemas-microsoft-com:office:office""" &
vbCrLf & _
            " xmlns:x=""urn:schemas-microsoft-com:office:" & "excel""" &
vbCrLf & _
            " xmlns:ss=""urn:schemas-microsoft-com:" &
"office:spreadsheet"">" & vbCrLf & _
            " <Styles>" & vbCrLf & _
            "  <Style ss:ID=""Default"" ss:Name=""Normal"">" & vbCrLf & _
            " <Alignment ss:Vertical=""Bottom""/>" & vbCrLf & _
            " <Borders/>" & vbCrLf & _
            " <Font ss:FontName=""MS Sans Serif""/>" & vbCrLf & _
            " <Interior/><NumberFormat/><Protection/>" & vbCrLf & _
            " </Style>" & vbCrLf & _
            "<Style ss:ID=""BoldColumn"">" & vbCrLf & _
            " <Font x:Family=""Swiss"" ss:Bold=""1""/>" & vbCrLf & _
            " </Style>" & vbCrLf
    startExcelXML = startExcelXML & "<Style ss:ID=""StringLiteral"">" &
vbCrLf & _
            " <NumberFormat" & " ss:Format=""@""/>" & vbCrLf & _
            " </Style>" & vbCrLf & _
            " <Style ss:ID=""Decimal"">" & vbCrLf & _
            " <NumberFormat ss:Format=""0.0000""/>" & vbCrLf & _
            " </Style>" & vbCrLf & _
            " " & "<Style ss:ID=""Integer"">" & vbCrLf & _
            " <NumberFormat ss:Format=""0""/>" & vbCrLf & _
            " </Style>" & vbCrLf & _
            " <Style ss:ID=""DateLiteral"">" & vbCrLf & _
            " <NumberFormat ss:Format=""mm/dd/yyyy;@""/>" & vbCrLf & _
            " </Style>" & vbCrLf & _
            " <Style ss:ID=""NomiColonne"">" & vbCrLf & _
            "  <Borders>" & vbCrLf & _
            "   <Border ss:Position=""Bottom""
ss:LineStyle=""Continuous"" ss:Weight=""1""/>" & vbCrLf & _
            "   <Border ss:Position=""Left"" ss:LineStyle=""Continuous""
ss:Weight=""1""/>" & vbCrLf & _
            "   <Border ss:Position=""Right""
ss:LineStyle=""Continuous"" ss:Weight=""1""/>" & vbCrLf & _
            "   <Border ss:Position=""Top"" ss:LineStyle=""Continuous""
ss:Weight=""1""/>" & vbCrLf & _
            "  </Borders>" & vbCrLf & _
            " <Font ss:FontName=""Tahoma"" x:Family=""Swiss""
ss:Size=""9"" ss:Bold=""1""/>" & vbCrLf & _
            " <Interior ss:Color=""#C0C0C0"" ss:Pattern=""Solid""/>" &
vbCrLf & _
            " <NumberFormat/>" & vbCrLf & _
            " </Style>" & vbCrLf & _
            " " & "</Styles>" & vbCrLf
    Dim endExcelXML As String
    endExcelXML = "</Workbook>"
    Dim NFile As Integer
    NFile = FreeFile
    Open filename For Output As #NFile
    Print #NFile, startExcelXML
    Print #NFile, "<Worksheet ss:Name=""Sheet" & CStr(sheetcount) & """>"
    Print #NFile, "<Table>"
    'Creo la testata
    If Testata = True Then
        'Seconda riga contiene il numero di righe estratte
        Print #NFile, "<Row ss:Index=""2"">" & vbCrLf
        Print #NFile, "<Cell ss:StyleID=""BoldColumn""><Data
ss:Type=""String"">"
        Print #NFile, "Risultati: " & _
                       rs.RecordCount & " Righe</Data></Cell>"
        Print #NFile, "</Row>"
    End If
    'Riga con i nomi delle colonne
    Print #NFile, "<Row ss:Index=""4"">" & vbCrLf
    Dim x As Long
    For x = 0 To rs.Fields.Count - 1
        Print #NFile, "<Cell ss:StyleID=""NomiColonne""><Data
ss:Type=""String"">"
        Print #NFile, rs.Fields(x).Name
        Print #NFile, "</Data></Cell>"
    Next
    Print #NFile, "</Row>"
    Dim XMLstring As String
    rowCount = 0
    sheetcount = 0
    rs.MoveFirst
    Do While Not rs.EOF
        rowCount = rowCount + 1
        'if the number of rows is > 64000 create a new page to continue
output
        If rowCount = 64000 Then
            rowCount = 0
            sheetcount = sheetcount + 1
            Print #NFile, "</Table>"
            Print #NFile, "<WorksheetOptions
xmlns=""urn:schemas-microsoft-com:office:excel"">"
            Print #NFile, "<DoNotDisplayGridlines/>"
            If sheetcount = 0 Then
                'metto la testata solo sul primo foglio
                Print #NFile, "<FreezePanes/>"
                Print #NFile, "<SplitHorizontal>4</SplitHorizontal>"
                Print #NFile, "<TopRowBottomPane>4</TopRowBottomPane>"
                Print #NFile, "<ActivePane>2</ActivePane>"
            End If
            Print #NFile, "</WorksheetOptions>"
            Print #NFile, " </Worksheet>"
            Print #NFile, "<Worksheet ss:Name=""Sheet" &
CStr(sheetcount) & """>"
            Print #NFile, "<Table>"
        End If
        Print #NFile, "<Row>"
        Dim Y As Long
        For Y = 0 To rs.Fields.Count - 1
            If IsNull(rs(Y)) Then
                'E' un NULL, scrivo una stringa vuota
                XMLstring = "<Cell ss:StyleID=""StringLiteral""><Data
ss:Type=""String"">"
                XMLstring = XMLstring & "</Data></Cell>"
                Print #NFile, XMLstring
            Else
                Dim rowType As DataTypeEnum
                rowType = rs(Y).Type
                Select Case rowType
                    Case adVarChar, adVarWChar
                        XMLstring = CStr(rs(Y))
                        XMLstring = Trim(XMLstring)
                        'simboli propri dell'XML
                        XMLstring = Replace(XMLstring, "&", "&amp;")
                        XMLstring = Replace(XMLstring, ">", "&gt;")
                        XMLstring = Replace(XMLstring, "<", "&lt;")
                        'Lettere accentate
                        XMLstring = Replace(XMLstring, "à", "&agrave;")
                        XMLstring = Replace(XMLstring, "á", "&aacute;")
                        XMLstring = Replace(XMLstring, "è", "&egrave;")
                        XMLstring = Replace(XMLstring, "é", "&eacute;")
                        XMLstring = Replace(XMLstring, "ì", "&igrave;")
                        XMLstring = Replace(XMLstring, "í", "&iacute;")
                        XMLstring = Replace(XMLstring, "ò", "&ograve;")
                        XMLstring = Replace(XMLstring, "ó", "&oacute;")
                        XMLstring = Replace(XMLstring, "ù", "&ugrave;")
                        XMLstring = Replace(XMLstring, "ú", "&uacute;")
                        XMLstring = "<Cell
ss:StyleID=""StringLiteral"">" & "<Data ss:Type=""String"">" & _
                                    XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                    Case adDBDate, adDBTime, adDBTimeStamp
                        'Excel has a specific Date Format of YYYY-MM-DD
followed by
                        'the letter 'T' then hh:mm:sss.lll Example
2005-01-31T24:01:21.000
                        'The Following Code puts the date stored in XMLDate
                        'to the format above
                        Dim XMLDate As Date
                        Dim XMLDatetoString As String
                        XMLDate = CDate(rs(Y))
                        XMLDatetoString = ""
                        'Excel Converted Date
                        XMLDatetoString = CStr(Year(XMLDate)) & "-" &
IIf(Month(XMLDate) < 10, "0" & CStr(Month(XMLDate)), _
                        CStr(Month(XMLDate))) & "-" & IIf(Day(XMLDate) <
10, "0" & CStr(Day(XMLDate)), _
                        CStr(Day(XMLDate))) & "T" & IIf(Hour(XMLDate) <
10, "0" & CStr(Hour(XMLDate)), _
                        CStr(Hour(XMLDate))) & ":" & IIf(Minute(XMLDate)
< 10, "0" & CStr(Minute(XMLDate)), _
                        CStr(Minute(XMLDate))) & ":" &
IIf(Second(XMLDate) < 10, "0" & CStr(Second(XMLDate)), _
                        CStr(Second(XMLDate))) & ".000"
                        XMLstring = "<Cell
ss:StyleID=""DateLiteral""><Data ss:Type=""DateTime"">"
                        XMLstring = XMLstring & XMLDatetoString
                        XMLstring = XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                    Case adBoolean
                        XMLstring = "<Cell
ss:StyleID=""StringLiteral""><Data ss:Type=""String"">"
                        XMLstring = XMLstring & CStr(rs(Y))
                        XMLstring = XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                    Case adInteger, adSmallInt, adTinyInt
                        XMLstring = "<Cell ss:StyleID=""Integer""><Data
ss:Type=""Number"">"
                        XMLstring = XMLstring & Replace(CStr(rs(Y)),
",", ".")
                        XMLstring = XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                    Case adDecimal, adDouble, adSingle
                        XMLstring = "<Cell ss:StyleID=""Decimal""><Data
ss:Type=""Number"">"
                        XMLstring = XMLstring & Replace(CStr(rs(Y)),
",", ".")
                        XMLstring = XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                    Case adEmpty
                        XMLstring = "<Cell
ss:StyleID=""StringLiteral""><Data ss:Type=""String"">"
                        XMLstring = XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                    Case Else
                        XMLstring = "<Cell
ss:StyleID=""StringLiteral""><Data ss:Type=""String"">"
                        XMLstring = XMLstring & "</Data></Cell>"
                        Print #NFile, XMLstring
                End Select
            End If
        Next
        Print #NFile, "</Row>"
        rs.MoveNext
    Loop
    Print #NFile, "</Table>"
    Print #NFile, "<WorksheetOptions
xmlns=""urn:schemas-microsoft-com:office:excel"">"
    Print #NFile, "<DoNotDisplayGridlines/>"
    If sheetcount = 0 Then
        'metto la testata solo sul primo foglio
        Print #NFile, "<FreezePanes/>"
        Print #NFile, "<SplitHorizontal>4</SplitHorizontal>"
        Print #NFile, "<TopRowBottomPane>4</TopRowBottomPane>"
        Print #NFile, "<ActivePane>2</ActivePane>"
    End If
    Print #NFile, "</WorksheetOptions>"
    Print #NFile, " </Worksheet>"
    Print #NFile, endExcelXML
    Close #NFile
    ExportToExcel = "+OK Esportazione in Excel completata."
    Exit Function
err:
    ExportToExcel = err.Description
End Function

 scritta una testata o no e lei ti scrive un excel.
Grazie mille, ci lavoro un pochino e vedo che viene fuori.

 comunque il loro bel foglietto di excel da pasticciare.
Sono procedure "assodate" con file che vengono consultati da tempo in quel
modo. Devo capire se è possibile cambiare qualcosa per loro. O altrimenti
si tengono un pc acceso e loggato che gli fa le esportazioni.

Ah, ovviamente è solo un inizio.
Volendo puoi approfondire qui:
http://msdn.microsoft.com/en-us/library/Aa140066#odc_xmlss_ss:Workbook
Nicola

Avrei delle procedure un po' piů complesse, da riportare come servizio
(aggiornare periodicamente dei file xls senza che ci sia un utente
loggato).
Si parla di mettere filtri, dare stili e formattazioni, fare grafici e
formule.
*************************************************
Il mio cent.
Da un cliente ho questa situazione.
Sul server ho un file .xls che si aggiorna
ogni ora prelevando i dati dal server con
il db. Importati i dati, esegue altre routine
che aggiornano anche le formattazioni sui fogli
ed i riferimenti per i grafici.
Salva poi una copia di alcuni fogli(senza formule e codici,
quindi solo con i dati) come nuovo
file in una directory shared disponibile per gli utenti autorizzati.
Tempo del ciclo di importazione/file shared disponibile: 1'20" come
media.
Il file lavora 5 giorni alla settimana senza essere mai chiuso
(in azienda il venerdě sera *spengono tutto*) ma qui
in studio  ho testato una cosa simile per tre mesi senza spegnere
il server e senza avere mai
nessun tipo di problema.
Excel *tiene*.
Sempre qui in studio ho fatto questo test di
long run ;-):
Una classe che ogni minuto veniva istanziata per scrivere alcuni dati
in SQL Server tramite ADO ed una SP sul db.
Ogni ora prelevavo i dati della tabella dal db e li importavo
in un nuovo file formattandolo come report e salvandolo.
Il tutto *girava* in una macchina virtuale che ho cercato di *stressare*
utilizzandola anche per altre cose. Il test č durato 22 giorni.
Lo so, sono Excelcentrico ma, in determinati
contesti, in due ore di lavoro risolvo... ;-)
---------------------------
Mauro Gamberini
Microsoft MVP - Excel
http://www.riolab.org/
http://www.maurogsc.eu/
 

 contesti, in due ore di lavoro risolvo... ;-)
Beh si, il problema è che nel caso il server non sarebbe proprio
accessibile, e comunque si spegne.
E non possono certo loggarlo ogni mattina.