Hallo zusammen,
ich habe eine Windowsform [Arbeitsmaske]
in dieser Form habe ich ein DataGridView [dGvexcel]
in meiner Funktion
Form1_Load
rufe ich meine Funktion
dGvexcel_initialisieren();
auf
in dieser setze ich Parameter wie:
dGvexcel.ColumnCount = 10;
dGvexcel.ColumnHeadersVisible = true;
// Set the column header style.
DataGridViewCellStyle columnHeaderStyle = new DataGridViewCellStyle();
columnHeaderStyle.BackColor = Color.Beige;
columnHeaderStyle.Font = new System.Drawing.Font("Arial", 10, FontStyle.Bold);
dGvexcel.ColumnHeadersDefaultCellStyle = columnHeaderStyle;
// Spalten hinzufügen
dGvexcel.Columns[0].Name = "Projektnummer";
dGvexcel.Columns[1].Name = "Auftrag";
dGvexcel.Columns[2].Name = "Priorität";
dGvexcel.Columns[3].Name = "Team";
dGvexcel.Columns[4].Name = "Zusatz";
anschließend rufe ich meine Funktion
dgv_fuellen();
auf
in dieser füttere ich das DGV mit Daten aus einer Excelliste. (das funktioniert auch perfekt)
Nun habe ich das DataGridViewAutoFilter entdeckt und mir hierzu auch die MS Seite angeschaut,
allerdings blicke ich es gerade nicht, wo ich was einsetzen soll.
Wenn ich diese Funktion
foreach (DataGridViewColumn col in dGvexcel.Columns)
{
col.HeaderCell = new DataGridViewAutoFilterColumnHeaderCell(col.HeaderCell);
}
in meine
dGvexel_initialisieren();
setze
sehe ich zwar die dropdown Pfeile in jeder Spalte, aber sobald ich draufklicke kommt ein Fehler mit den Funktionen DataSource und DataBinding,
bei denen ich nicht blicke, wo ich die reinsetzen muss...
Vielleicht kann mir einer weiterhelfen.
Danke im Voraus.
Gruß
in dem Bild sieht man die Fehlermeldung
und wie die Dropdownpfeile angezeigt werden (so wie ich mir das vorstelle)
Hallo,
schaue dir bitte den Part Dependencies hier an: Building a Drop-Down Filter List for a DataGridView Column Header Cell
Grüße
**:::
ja da war ich schon drauf,
und ich blick gerade hauptsächlich die Funktion
// Add this code to the form Load event handler.
dataGridView1.DataSource = customersBindingSource;
umgeschrieben hab ich des dann so:
dGvexcel.DataSource = customersBindingSource;
aber wo hole ich mein bindingsource etc.?
da häng ich gerade bzw. blicke es nicht... 😦
Hallo,
du musst ein BindingSource Objekt erzeugen und dein Excel als BindingSource.DataSource, damit kannst du dein DGV zuweisen.
Schaue dir das Beispiel an BindingSource-Klasse (am Ende der Seite)
Grüße
**:::
heißt des, dass ich meine separate Funktion
dgv_fuelle()
wegfallen lassen kann?
(ausschnitt aus der Funktion)
public void dgv_fuellen()
{
dgverledigt = 0;
dgvzeile = 6;
do
{
Microsoft.Office.Interop.Excel.Application dgvxlapp = new Microsoft.Office.Interop.Excel.Application();
dgvxlapp.Visible = false;
Workbook dgvwb;
object missing = System.Reflection.Missing.Value;
try
{
System.Threading.Thread.Sleep(300); //Kurze Wartetimer
dgvwb = dgvxlapp.Workbooks.Open(
verbindung_zu_definitionen.getPfad(),
ExcelKonstanten.UpdateLinks.DontUpdate,
ExcelKonstanten.ReadWrite,
ExcelKonstanten.Format.Nothing,
"", // Passwort
"", // WriteResPasswort
ExcelKonstanten.IgnoreReadOnlyRecommended,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
"", // Trennzeichen
ExcelKonstanten.Editable,
ExcelKonstanten.Notify,
ExcelKonstanten.Converter.Default,
ExcelKonstanten.DontAddToMru,
ExcelKonstanten.Local,
ExcelKonstanten.CorruptLoad.NormalLoad
);
// Arbeitsblätter lesen
Sheets sheets = dgvwb.Worksheets;
// ein Arbeitsblatt auswählen…
Worksheet dgvws = (Worksheet)sheets.get_Item("CM");
//erste leere Zeile suchen
do
{
object dgvwertzelle = dgvxlapp.Cells[dgvzeile, spalte_excel_erledigt].Value2; //erldigt feld
string wert_projektnummer = dgvxlapp.Cells[dgvzeile, spalte_excel_Projektnummer].Value.ToString(); //Typumwandlung, da sonst Fehler beim sortieren
object wert_auftrag = dgvxlapp.Cells[dgvzeile, spalte_excel_Auftrag].Value2;
object wert_prio = dgvxlapp.Cells[dgvzeile, spalte_excel_Prio].Value2;
object wert_team = dgvxlapp.Cells[dgvzeile, spalte_excel_Team].Value2;
object wert_zusatz = dgvxlapp.Cells[dgvzeile, spalte_excel_Zusatz].Value2;
object wert_teilenummer = dgvxlapp.Cells[dgvzeile, spalte_excel_TnAnlage].Value2;
object wert_eingelastet = dgvxlapp.Cells[dgvzeile, spalte_excel_Eingelastet].Value2; //Fehler mit Datum
object wert_zieltermin = dgvxlapp.Cells[dgvzeile, spalte_excel_Zieltermin].Value2;
object wert_konstrukteur = dgvxlapp.Cells[dgvzeile, spalte_excel_Konstrukteur].Value2;
object wert_projektleiter = dgvxlapp.Cells[dgvzeile, spalte_excel_Projektleiter].Value2;
//wert_zieltermin = wert_zieltermin.ToString();//typeof(DateTime);
wert_eingelastet = Convert.ToDateTime(wert_eingelastet);
wert_zieltermin = Convert.ToDateTime(wert_zieltermin);
if (dgvwertzelle != null)
{
dgverledigt = dgverledigt + 1;
}
else
{
dGvexcel.Rows.Add(wert_projektnummer,wert_auftrag, wert_prio, wert_team,wert_zusatz,wert_teilenummer, wert_eingelastet,wert_zieltermin, wert_konstrukteur, wert_projektleiter);
}
lbl_zeile.Text = Convert.ToString(dgvzeile - dgverledigt - 5);
dgvzeile = dgvzeile + 1;
binding_excel.DataSource = dgvws;
} while (dgvws.Cells[dgvzeile, 1].Value != null);
dgvwb.Close(true, missing, false); //Workbook schließen & speichern
dgvxlapp.Quit(); //Excel beenden
System.Threading.Thread.Sleep(300); //Kurze Wartetimer
dgvexcelfehler = 0;
}
In meiner Form_load habe ich nun ein
binding_excel = new BindingSource();
in dem Excelaufruf habe ich das binding drin,
aber irgendwie kommt mir das falsch vor.... 😦
Hallo,
zuviel Code ... ich lese kein Codes, die mehr als 20 Zeilen beinhalten, da keine Zeit und zu faul 😜
Excel kannst du über OLEDB direkt auslesen, ohne Excel zu öffnen, damit ise es einfacher zu arbeiten und schneller
System.Data.OleDb.OleDbConnection oledbConnection;
System.Data.DataSet dataSet;
System.Data.OleDb.OleDbDataAdapter dataAdapter;
oledbConnection = new System.Data.OleDb.OleDbConnection(@"provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\test.xls';Extended Properties=Excel 8.0;");
dataAdapter = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", oledbConnection);
dataAdapter.TableMappings.Add("Table", "test");
dataSet = new System.Data.DataSet();
dataAdapter.Fill(dataSet);
// z.B. dann
bindingSource.DataSource = dataSet.Tables[0];
Grüße
**:::
😃
kenn ich irgendwoher (bin auch lesefaul)
ok des mit dem OLEDB kenn ich gar nicht, jetzt will ich erst versuchen das auf die herkömmliche art zu machen
hier der Code in Kurzform 😃
-excel öffnen
-excel zeile für zeile in Variable einlesen
-Variable Zeile für Zeile ins dGvexcel mit .Rows.Add
und wie kann ich jetzt diese Daten zuordnen?
binding_excel.DataSource = ????;
oder brauch ich das nicht mehr, da ja eigtentlich mein DGV gefüllt ist?
Hallo,
Excel Applikation öffnet man nur, wenn man ein Excel Datei direkt manipulieren möchte, nicht aber wenn man nur Daten ausliest, das ist nicht performant und falsch. Mach lieber mit OLEDB.
Wenn du aber nicht anders willst, kannst du die Exceldaten in einer DataTable eines DataSet ablegen und dann als DataSource deines BindingSource Objekt verwenden. That's it.
Grüße
**:::
ja gut in der Funktion les ich nur, aber in einem anderen Teil des programms schreibe ich auch oder ändere die formatierung.
mh ok
dann versuch ich das mal irgendwie zu handhaben,
von dem DataTable und DataSet hab ich auch noch nie was gehört 🤔
(ja bin noch blutiger Anfänger 🙁 )
danke dir aber schon mal ...
Hallo,
bitte lesen Verwenden des DataSet Objekts (und vorsorglich [Hinweis] Wie poste ich richtig? Punkt 1.1.1
Grüße
**:::
Hallo,
also ich komm nicht weiter mit den ganzen bindings und sources.
In meine Form1_Load habe ich versucht die BindingDinger einzufügen:
....
//Versuch Excel in Form mit DataGridView
binding_excel = new BindingSource();
dGvexcel_initialisieren();
dgv_fuellen();
binding_excel.DataSource = GetExcelDataSet(verbindung_zu_definitionen.getPfad(), true);
dGvexcel.DataSource = binding_excel;
}
In die Funktion
dGvexcel_initialisieren();
habe ich den Handler eingebaut:
dGvexcel.BindingContextChanged += new EventHandler(dGvexcel_BindingContextChanged);
mit diesem sollen ja die DropdownButtons in mein GridView Header reinkommen.
private void dGvexcel_BindingContextChanged(object sender, EventArgs e)
{
if (dGvexcel.DataSource == null) return;
foreach (DataGridViewColumn col in dGvexcel.Columns)
{
col.HeaderCell = new
DataGridViewAutoFilterColumnHeaderCell(col.HeaderCell);
}
dGvexcel.AutoResizeColumns();
}
Meine GetDataSet Methode habe ich versucht nach deinem Tip (vbprogger) mit dem OLEDB
die sieht dann so aus:
public static DataSet GetExcelDataSet(string excelFile, bool hasHeaders)
{
var hdr = hasHeaders ? "Yes" : "No";
string strConn;
if (excelFile.Substring(excelFile.LastIndexOf('.')).ToLower() == ".xlsx")
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFile +
";Extended Properties=\"Excel 12.0 Macro;HDR=" + hdr + ";IMEX=1\"";
else
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFile + ";Extended Properties=\"Excel 8.0;HDR=" + hdr +
";IMEX=1\"";
var output = new DataSet();
using (var conn = new OleDbConnection(strConn))
{
conn.Open();
var schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
if (schemaTable != null)
foreach (DataRow schemaRow in schemaTable.Rows)
{
var tableName = schemaRow["CM"].ToString();
if (tableName.LastIndexOf("'", StringComparison.Ordinal) < tableName.Length - 1)
continue;
try
{
var cmd = new OleDbCommand("SELECT * FROM [" + tableName + "]", conn) { CommandType = CommandType.Text };
var outputTable = new System.Data.DataTable(tableName);
new OleDbDataAdapter(cmd).Fill(outputTable);
}
catch (Exception ex)
{
throw new Exception(ex.Message + "Sheet:" + tableName + ".File:" + excelFile, ex);
}
}
conn.Close();
}
return output;
}
Irgendwie will das alles nicht so wie es sein soll.
Und so einfach wie es in den Foren steht ist das auch nicht...
vlt. kann mir einer noch n Tip geben ...
Danke.
Gruß
Es fehlt noch
output.Tables.Add(outputTable);
in der GetExcelDataSet-Methode.
Du solltest aber passende Fehlerbeschreibungen liefern und nicht "Irgendwie will das alles nicht so wie es sein soll."
Und den Umgang mit dem Debugger solltest du auch lernen, dann hättest du gesehen, daß das DataSet nirgends gefüllt wird: [Artikel] Debugger: Wie verwende ich den von Visual Studio?
ok danke TH69
habe es eingefügt, nun ist mir aber aufgefallen,
dass er in der Funktion
public static DataSet GetExcelDataSet(string excelFile, bool hasHeaders)
nach dem for schleifen einstieg
foreach (DataRow schemaRow in schemaTable.Rows)
{
var tableName = schemaRow["CM"].ToString();
gar nicht mehr weiter macht, sondern mein UI aufruft und dann kann ich es normal bedienen (wie davor ohne die AutoGrid DropDownbuttons im Header des DGV´s)
Ich geh dem mal auf den Grund und melde mich wieder, falls ich nicht weiter komme.
Ausser es sieht ein Profi auf anhieb 😃
Gruß
hallo zusammen,
ich habe es nun geschafft, dass sich das DGV mit dem OLEDB füllen läßt und der Filter geht nun auch.
Meine Füllen Funktion:
public void dgv_fuellen()
{
try
{
var excelFile = verbindung_zu_definitionen.getPfad();
var hdr = "Yes"; //hasHeaders ? "Yes" : "No";
var binding_excel = new BindingSource();
string connectionString;
//Prüfen welches Excel OLEDB geladen werden soll
if (excelFile.Substring(excelFile.LastIndexOf('.')).ToLower() == ".xlsx")
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFile +
";Extended Properties=\"Excel 12.0 Macro;HDR=" + hdr + ";IMEX=1\"";
else
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFile + ";Extended Properties=\"Excel 8.0;HDR=" + hdr +
";IMEX=1\"";
//Alle Spalten von Tabelle1 lesen
var adapter = new OleDbDataAdapter("SELECT * FROM [CM$]", connectionString);
//Verbindung zur Tabelle aufbauen
var ds = new DataSet();
//Zu lesende Tabelle angeben
adapter.Fill(ds, "CM");
//Tabelle auswählen
dt_filter = ds.Tables["CM"];
//Binden da DataGridViewAutoFilter nur mit einem Binding arbeiten
binding_excel.DataSource = dt_filter;
//Mit DGV verknüpfen
dGvexcel.DataSource = binding_excel;//dt_filter; //Daten mit dem DGV verknüpfen
}
catch (Exception fehler_fuellen)
{
MessageBox.Show("Die Daten konnten nicht geladen werden, folgendes Problem trat auf:\n" + fehler_fuellen + "\n sollte das Problem weiterhin bestehen, \n" +
"wenden sie sich an:\n fheb@de.festo.com", "Datenfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
//nicht benötigte Spalten ausblenden
dGvexcel.Columns["Angebot"].Visible = false;
dGvexcel.Columns["Auftrags Nr"].Visible = false;
dGvexcel.Columns["erledigt"].Visible = false;
dGvexcel.Columns["Beschreibung"].Visible = false;
dGvexcel.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}//Ende DGV füllen neu
Teile aus meiner Form_Load Funktion:
//Versuch Excel in Form mit DataGridView und DGVAutoFilter
dGvexcel.BindingContextChanged += new EventHandler(dGvexcel_BindingContextChanged);
dGvexcel_initialisieren();
dgv_fuellen();
Die BindingContextChange Funktion in meine Hauptklasse Form1:
private void dGvexcel_BindingContextChanged(object sender, EventArgs e)
{
if (dGvexcel.DataSource == null) return;
foreach (DataGridViewColumn col in dGvexcel.Columns)
{
col.HeaderCell = new
DataGridViewAutoFilterColumnHeaderCell(col.HeaderCell);
}
dGvexcel.AutoResizeColumns();
}
und ganz wichtig war anscheinend die Rückstzefunktion meines DGV´s:
public void dgvclear()
{
var dgvtable = (dGvexcel.DataSource as BindingSource).DataSource as System.Data.DataTable;
dgvtable.Rows.Clear();
}
Jetzt will ich noch versuchen die Spaltenbreite an mein DGV anzupassen, irgendwie geht das mit dem
dGvexcel.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
nicht richtig.
Ah und den Header farbig markieren wenn in dieser Spalte gefiltert wurde...
Vielleicht weiß einer ja noch Rat, ansonsten versuch ich mein Glück und melde mich wieder 😄
Danke nochmal an alle.
Gruß
ok ich habe es hinbekommen mit der spaltenaufteilung,
ich hab in meiner dGvexcel_initialisieren() Methode die Funktion:
dGvexcel.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
eingebaut, da mir gesagt wurde, dass "AutoSizeColumns" sich nicht auf die vorgegebene Breite meines DGV´s bezeieht, sondern sich auf den Inhalt der Spalten bezieht und jede Spalte so breit wie der längste Eintrag in der Spalte macht.