Zadáním je načíst řádky z listu excelu a hledat řádky, kde je v daném sloupci červený font. EXCEL : Pokusný list sešitu má na prvním řádku definované záhlaví, třeba čtyři sloupce, kde nyní v posledním se očekává výskyt červeného fontu písma. Vytvořit tabulku, pár řádků s daty, v posledním sloupci někde červeně a uložit sešit excelu. Vzorek nebyl dodán, lze tedy plně rozvinout fantazii. VS : Do nového formu nového projektu vložit kód a opravit cestu a název listu v kódu. Po spuštění načte data z listu do datatable s pomocným sloupcem pro barvu fontu, která se předá jako zdroj pro datagridview, kde se dle očekávání zobrazí data z použité oblasti vašeho pokusného listu excelu. V opačném případě lituji... Střídavým klepnutím myší na rohovou buňku, kde se kříží záhlaví řádků a sloupců, lze ovlivnit zobrazení všechna data nebo jen řádky, kde bylo to červené písmo. Klepnutím myši na záhlaví řádku se zobrazí jeho index v datatable a v excelu. Stejně tak by měl jít zjistit index po seřazení některého sloupce datagridview. Tady se snažím poprat s indexy řádků :
Public Class Form1
Private dgv As DataGridView
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
dgv = New DataGridView
With dgv
.Dock = DockStyle.Fill
.AllowUserToAddRows = False
End With
Me.Controls.Add(dgv)
AddHandler dgv.CellClick, AddressOf dgv_CellClick
Dim workbook_path As String = "C:\Documents and Settings\Vy\Dokumenty\Sešit1.xls(x)"
Dim worksheet_name As String = "List1"
Dim excel_app, excel_wb As Object
Dim excel_type As Type = Type.GetTypeFromProgID("Excel.Application")
excel_app = Activator.CreateInstance(excel_type)
excel_wb = excel_app.Workbooks.Open(workbook_path)
Dim excel_rng As Object = excel_wb.Worksheets(worksheet_name).UsedRange
Dim dt As New DataTable
For r As Integer = 1 To excel_rng.Rows.Count
If r = 1 Then
For c As Integer = 1 To excel_rng.Columns.Count
With dt
.Columns.Add(excel_rng.Cells(r, c).Value)
End With
Next
dt.Columns.Add("Font")
Else
Dim a_1 As Object = excel_app.Transpose(excel_app.Transpose(excel_rng.Rows(r).Value))
Dim a_0(0 To excel_rng.Columns.Count) As Object
For i As Integer = 0 To excel_rng.Columns.Count - 1
a_0(i) = a_1(i + 1)
Next
Dim redfont_column_index = excel_rng.Columns.Count
a_0(excel_rng.Columns.Count) = excel_rng.Cells(r, redfont_column_index).Font.Color
dt.Rows.Add(a_0)
End If
Next
dgv.DataSource = dt
excel_wb.Close(False)
excel_wb = Nothing
excel_app.Quit()
excel_app = Nothing
End Sub
Private Sub dgv_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs)
If e.RowIndex < 0 And e.ColumnIndex < 0 Then
Dim dv As DataView = DirectCast(dgv.DataSource, DataTable).DefaultView
dv.RowFilter = IIf(dv.RowFilter = String.Empty, "[Font]=255", String.Empty)
dgv.Columns("Font").Visible = dv.RowFilter = String.Empty
ElseIf e.ColumnIndex < 0 Then
Dim dr As DataRow = CType(dgv.Rows(e.RowIndex).DataBoundItem, DataRowView).Row
Dim idr As Integer = dr.Table.Rows.IndexOf(dr)
MsgBox("Index řádku v datatable :" & idr & vbNewLine & _
"Index řádku v excel range :" & (idr + 2))
End If
End Sub
End Class
Vlastní uložení nazpět je na Vašem uvážení, index řádku v excelu je známý, předáte hodnotu ze sloupce a řádku do Range a uložíte metodou Workbook.Save. Rozdíl 2 mezi indexem v datatable a v range způsoben tím, že číslování řádků, je buď od nuly nebo od jedné a excel má v prvním řádku záhlaví. V závislosti na tom, zda se bude ukládat vše najednou třeba před zavřením nebo po provedení změny si přestěhujte potřebné proměnné do deklarační části formuláře, budete-li chtít události datagridview, tak si přidejte WithEvents, nebo datagridview a příp. další prvky vytvořte v návrhu formu a přejmenujte. Před zavřením formu zajistit zavření excelu a uvolnění objektu, aby instance nezůstávaly viset, hledat FinalReleaseComObject je to tady určitě několikrát. LISTVIEW : Pokud přetrvá touha plnit data do listview, lze se případně inspirovat příkladem zde na webu a předat datatable jako zdroj DataListView poděděném z ListView, ale čeká Vás další spousta práce, kterou datagridview bezpochyby ušetří. Další podrobnosti najdete zde na webu, pouze ukázka :
Public Class DataListView
Inherits ListView
Public Sub SetDataSource(ByVal fromDataTable As DataTable)
Me.Items.Clear()
Me.BeginUpdate()
For i As Integer = 0 To fromDataTable.Rows.Count - 1
Dim lvItem As ListViewItem
lvItem = Me.Items.Add(fromDataTable.Rows(i).Item(0).ToString)
For j As Integer = 1 To fromDataTable.Columns.Count - 1
lvItem.SubItems.Add(fromDataTable.Rows(i).Item(j).ToString)
Next j
Next i
Me.EndUpdate()
End Sub
Public Sub New()
Me.View = Windows.Forms.View.Details
Me.HideSelection = False
Me.GridLines = True
End Sub
End Class
Podmínka s barvou mi fungovala, tak to zkuste a vylepšete si k obrazu svému.
|