Snippet

Třídá pro práci s excelem

Přidáno: 5.3.2010       Kategorie: VB.NET - Komponenty       Autor: Honza Dědek

Při své práci jsem narazil na nutnost vytvořit nějáké specifické sestavy v excelu.

Potřeboval jseml otevřít .xlt šablonu, nalít do ní nějáká data a nechat uživatele aby si výsledný soubor uložil. Požadovaná šablona neměla bohužel databázovou strukturu, takže bylo nutné data ukládat do předem určených buňek manuálně. Navíc jsem potřeboval využívat VBA.

Po vyřešení jsem narazil ještě na jeden problém a to ten, že i po uzavření instance excelu se neukončil její proces a tak dál zabírala paměť (navíc sešit který byl takto otevřený šel znovu otevřít pouze pro čtení).

To se mi taky podařilo vyřešit a výsledek je třída (viz. níže). Je to první verze, takže počítám že v případě potřeby tam přibudou další funkce.

Některé funkce (např. pro čtení a zápis dat) tam jsem jenom pro pohodlnost. K jednotlivým komponentám až na úroveň buněk je možné samozřejmě přistupovat i standartně přes Worksheets.

Kód mi spolehlivě funguje na Office 2003 i Office 2007




Komentář:

- při vytváření objektu je možné si vybrat, zda se zviditelní uživatelské rozhraní, nebo zda si nejdřív doplníte na pozadí data

- sešit je možné průběžně ukládat

- při uzavření si můžete zvolit, zda se má sešit uložit a zda se má zavřít i uživatelské rozhraní excelu (pouze pokud je zobrané, tzn. Visible=True). Pokud nechcete uživatelské rozhraní zavírat, zavoláte metodu CloseExcel s prvním parametrem False. Dojde pouze ke zničení objektů excelu které třída používá a k uvolnění procesu dojde bezprostředně poté, co uživatel zavře excel manuálně. Pokud by jste metodu CloseExcel nezavolali, proces dál poběží i po manuálním uzavření excelu (viz. výše problém s uzavíráním)



Aby to všechno fungovalo, musíte mít nareferencované příslušné knihovny MS Office.

Jsou to:

Microsoft Excel 11.0 Object Library
Microsoft Office 11.0 Object Library
Microsoft Visual Basic for Applications Extensibility 5.3

(Pokud máte nainstalované novější office a tím i novější verze knihoven, mělo by to fungovat taky)


Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices


Public Class ClassExcel
    Implements IDisposable

    Private _disposeWithCloseUI As Boolean = True
    Private _disposing As Boolean = True



#Region "Properties"

    ''' <summary>
    ''' Cesta k souboru
    ''' </summary>
    ''' <remarks></remarks>
    Private _path As String
    Public ReadOnly Property Path() As String
        Get
            Return _path
        End Get
    End Property




    ''' <summary>
    ''' List Excelu
    ''' </summary>
    ''' <remarks></remarks>
    Private _workSheet As Excel.Worksheet
    Public Property WorkSheet() As Excel.Worksheet
        Get
            Return _workSheet
        End Get
        Set(ByVal value As Excel.Worksheet)
            _workSheet = value
        End Set
    End Property




    ''' <summary>
    ''' Sešit
    ''' </summary>
    ''' <remarks></remarks>
    Private _workbook As Excel.Workbook
    Public Property Workbook() As Excel.Workbook
        Get
            Return _workbook
        End Get
        Set(ByVal value As Excel.Workbook)
            _workbook = value
        End Set
    End Property




    ''' <summary>
    ''' Instance Excelu
    ''' </summary>
    ''' <remarks></remarks>
    Private _excelApplication As Excel.Application
    Public Property ExcelApplication() As Excel.Application
        Get
            Return _excelApplication
        End Get
        Set(ByVal value As Excel.Application)
            _excelApplication = value
        End Set
    End Property




    ''' <summary>
    ''' Jméno listu na kterém se budou provádět změny
    ''' </summary>
    ''' <remarks></remarks>
    Private _sheetName As String
    Public Property SheetName() As String
        Get
            Return _sheetName
        End Get
        Set(ByVal value As String)
            _sheetName = value
            Me.WorkSheet = Me.Workbook.Sheets(Me.SheetName)
        End Set
    End Property




    ''' <summary>
    ''' Zobrazení UI
    ''' </summary>
    ''' <remarks></remarks>
    Private _visible As Boolean
    Public Property Visible() As Boolean
        Get
            Return _visible
        End Get
        Set(ByVal value As Boolean)
            _visible = value
            Me.ExcelApplication.Visible = value

        End Set
    End Property




    ''' <summary>
    ''' Indikuje zda se před uzavřením provede uložení změn
    ''' </summary>
    ''' <remarks></remarks>
    Private _saveBeforeClosing As Boolean = True
    Public Property SaveBeforeClosing() As Boolean
        Get
            Return _saveBeforeClosing
        End Get
        Set(ByVal value As Boolean)
            _saveBeforeClosing = value
        End Set
    End Property


#End Region



#Region "PrivateMethods"

    Sub New(ByVal filePath As String, ByVal sheetName As String, ByVal visible As Boolean)

        If IO.File.Exists(filePath) = False Then 'kontrola zda zadaný soubor existuje
            MsgBox("Neplatná cesta k souboru", MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "Neplatná cesta")
            _disposeWithCloseUI = False
            _disposing = False
            Me.Finalize()
            Exit Sub
        End If

        _excelApplication = New Excel.Application
        _path = filePath
        _sheetName = sheetName


        Me.Workbook = Me.ExcelApplication.Workbooks.Open(Me.Path)
        Me.WorkSheet = Me.Workbook.Sheets(Me.SheetName)
        Me.Visible = visible
    End Sub




    Protected Overrides Sub Finalize()
        Me.Dispose()
    End Sub

#End Region



#Region "PublicMethods"

    Public Sub CloseExcel(ByVal CloseUI As Boolean)

        If Me.SaveBeforeClosing = True Then SaveChanges() 'uložení změn


        If CloseUI = True Or Me.Visible = False Then
            _disposeWithCloseUI = True
        Else
            _disposeWithCloseUI = False
        End If

        Me.Finalize()

    End Sub




    Public Sub SaveChanges()
        Me.Workbook.Save() 'uložení změn
    End Sub




    Public Sub WriteData(ByVal sheetName As String, ByVal Range As String, ByVal Value As Object, Optional ByVal offsetRow As Integer = 0, Optional ByVal offsetColumn As Integer = 0)

        Me.SheetName = sheetName

        If offsetRow = 0 And offsetColumn = 0 Then
            Me.WorkSheet.Range(Range).Value = Value
        Else
            Me.WorkSheet.Range(Range).Offset(offsetRow, offsetColumn).Value = Value
        End If

    End Sub




    Public Function ReadData(ByVal sheetName As String, ByVal Range As String, Optional ByVal offsetRow As Integer = 0, Optional ByVal offsetColumn As Integer = 0)
        Me.SheetName = sheetName

        If offsetRow = 0 And offsetColumn = 0 Then
            Return (Me.WorkSheet.Range(Range).Value)
        Else
            Return (Me.WorkSheet.Range(Range).Offset(offsetRow, offsetColumn).Value)
        End If
    End Function




    Public Sub SelectRange(ByVal sheetName As String, ByVal range As String)

        Me.SheetName = sheetName

        Me.WorkSheet.Range(range).Select()
    End Sub




    Public Sub Dispose() Implements IDisposable.Dispose

        If _disposing = False Then Exit Sub

        If _disposeWithCloseUI = True Then
            If Me.SaveBeforeClosing = True Then Me.SaveChanges()
            Me.ExcelApplication.DisplayAlerts = False
            Me.ExcelApplication.Quit()
        End If


        GC.Collect()
        GC.WaitForPendingFinalizers()

        Marshal.FinalReleaseComObject(Me.WorkSheet)
        Marshal.FinalReleaseComObject(Me.Workbook)
        Marshal.FinalReleaseComObject(Me.ExcelApplication)

        GC.SuppressFinalize(Me)


    End Sub



#End Region








End Class
 
 

VBNET.CZ | © 2007 Tomáš Herceg, Tomáš Jecha | Kopírování a přejímání jakéhokoliv obsahu z tohoto webu je bez písemného svolení autorů zakázáno.