none
Excel otomasyonu ve Thread kullanımında 'HRESULT özel durum döndürdü: 0x800A01A8' hatası RRS feed

  • Soru

  • vb 2017 sürümünde geliştirmeye çalıştığım programda, 2010 excel'den aldığım verileri(yaklaşık 6000 satır 30 sütun) Listviewde göstermeye çalışıyorum. kayıt sayısı çok çok fazla olduğundan ekran donuyor. netten bulduğum bir örnek üzerinden thread kullunarak yapmak istediğimde "HRESULT özel durum döndürdü: 0x800A01A8" hatasını alıyorum. threading konusunda çok fazla bilgim yok. hatanın nedeni ile çözüm yolu hakkında yardım edersiniz çok sevinirim.

    Kod :

    Imports System.Threading

    Public Class Form3
        Private xl As New Object
        Private wb As New Object
        Private dosya As String

        Private sonsatir As Long
        Dim lw As New ListViewItem
        Private sayfa As Object
        Private thrBilgial As System.Threading.Thread


        Private Sub VeriAlToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles VeriAlToolStripMenuItem.Click
            opf1.ShowDialog()
            dosya = opf1.FileName
            If dosya.Length > 0 Then
                MsgBox("Açılaçak Dosya : " & dosya.ToString)
                Dim xl As Object = CreateObject("excel.application")
                Dim wb As Object
                wb = xl.workbooks.open(dosya.ToString)
                sayfa = wb.worksheets(1)
                'xl.visible = True
                If Microsoft.VisualBasic.Mid(sayfa.range("a1").text, 1, 6) <> "TF0837" Then
                    MsgBox("Hatalı Bir Form Açmaya Çalışıyorsunuz!!!", vbCritical + vbOKOnly)
                    wb.close(SaveChanges:=False)
                    xl.quit()
                    xl = Nothing
                    Exit Sub
                Else
                    sonsatir = sayfa.range("a65536").end(3).row
                    ProgressBar1.Value = 0
                    ProgressBar1.Maximum = sonsatir - 4


                    thrBilgial = New System.Threading.Thread(AddressOf bilgial)
                    thrBilgial.Start()
                End If

                wb.close(SaveChanges:=False)
                xl.quit()
                xl = Nothing
            End If
        End Sub

        Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            ProgressBar1.Width = Me.Width
        End Sub

        Private Sub bilgial()

            For i = 3 To (sonsatir - 2)
                If sayfa.range("I" & i).text <> "tk-web)" Then 'hata aldığım satır


                    On Error Resume Next
                    lw = ListView1.Items.Add(sayfa.range("b" & i).text)
                    lw.SubItems.Add(sayfa.range("I" & i).text)
                    lw.SubItems.Add(sayfa.range("L" & i).text)
                    lw.SubItems.Add(sayfa.range("Q" & i).text)
                    lw.SubItems.Add(sayfa.range("S" & i).text)
                    lw.SubItems.Add(sayfa.range("U" & i).text)
                    lw.SubItems.Add(sayfa.range("V" & i).text)
                    lw.SubItems.Add(sayfa.range("W" & i).text)
                    ListView1.Items.Add(lw)
                End If
                ProgressBar1.Value = i
                Next


        End Sub

    27 Mayıs 2022 Cuma 12:17

Yanıtlar

  • Buna XY Problemi deniyor. Yani gercek sorunuzu sormak yerine cozum oldugunu sandiginiz seyi soruyorsunuz. 

    6000 satir cok cok fazla oldugundan diyorsunuz. Size 6000 satirin cok fazla oldugunu dusunduren nedir? Sanirim yanlis gittiginiz yol. 2 noktada yanlisi bir yol aliyorsunuz:

    1) O excel datasini okumak icin OLE otomasyon yani COM kullaniyorsunuz. COM cagrilari yavasliklariyla bilinirler ve siz 6000 * 7 + bir miktar daha COM cagrisi yapiyorsunuz. Onun yerine basit sekilde baska metodlarla o veriyi okusaniz cok buyuk hiz farki olur. Size donmayi yasatan muhtemelen burasi. Makinenizin nasil bir sey oldugunu, ne kadar bir sureden bahsetmizi bilmiyoruz.

    2) Listview kullaniyorsunuz. Bu da bir yavaslik nedeni. DataGridView yerine ListView kullanmak icin ozel bir nedeniniz yoksa burada da hiz kazanabilirsiniz.

    Ben kendi makinemde (Ryzen 9 3900XT, 32 Gb RAM, Gen4 NVME) 8000 satili bir excel ornek dosyasi yaratarak denedim, Listview kullanarak formun goruntulenmesi 3.2 - 3.3 saniye. DataGridView ile 0.4 - 0.6 saniye.

    Excel'den veriyi EPPLus ile okudum (Nuget).

    Sub Main
    	Dim pck As ExcelPackage = New ExcelPackage("d:\temp\ExcelOrnek.xlsx")
    	Dim dt = pck.Workbook.Worksheets(0).Tables(0).ToDataTable()
    	ShowData(dt)
    End Sub
    
    Private Sub ShowData(ByVal t As DataTable)
    	Dim f As Form = New Form()
    	Dim lvOrnek As ListView = New ListView With {
    		.Dock = DockStyle.Fill,
    		.View = View.Details
    	}
    	f.Controls.Add(lvOrnek)
    	lvOrnek.LabelEdit = True
    	lvOrnek.AllowColumnReorder = True
    	lvOrnek.FullRowSelect = True
    	lvOrnek.GridLines = True
    
    	For Each c As DataColumn In t.Columns
    		lvOrnek.Columns.Add(c.ColumnName, -2)
    	Next
    
    	f.Show()
    	lvOrnek.Items.Clear()
    
    	For Each r As DataRow In t.Rows
    		Dim ekle As ListViewItem = New ListViewItem()
    		ekle.Text = r(0).ToString()
    
    		For i As Integer = 1 To t.Columns.Count - 1
    			ekle.SubItems.Add(r(i).ToString())
    		Next
    
    		lvOrnek.Items.Add(ekle)
    	Next
    
    	lvOrnek.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)
    End Sub
    

    Listview yerine DataGridView kullanarak:

    Sub Main
    	Dim pck As ExcelPackage = New ExcelPackage("d:\temp\ExcelOrnek.xlsx")
    	Dim dt = pck.Workbook.Worksheets(0).Tables(0).ToDataTable()
    	Dim f As Form = New Form()
    	Dim dgv = New DataGridView With { .Dock = DockStyle.Fill, .DataSource = dt }
    	f.Controls.Add(dgv)
    	f.Show()
    End Sub
    



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.

    27 Mayıs 2022 Cuma 15:53

Tüm Yanıtlar

  • Buna XY Problemi deniyor. Yani gercek sorunuzu sormak yerine cozum oldugunu sandiginiz seyi soruyorsunuz. 

    6000 satir cok cok fazla oldugundan diyorsunuz. Size 6000 satirin cok fazla oldugunu dusunduren nedir? Sanirim yanlis gittiginiz yol. 2 noktada yanlisi bir yol aliyorsunuz:

    1) O excel datasini okumak icin OLE otomasyon yani COM kullaniyorsunuz. COM cagrilari yavasliklariyla bilinirler ve siz 6000 * 7 + bir miktar daha COM cagrisi yapiyorsunuz. Onun yerine basit sekilde baska metodlarla o veriyi okusaniz cok buyuk hiz farki olur. Size donmayi yasatan muhtemelen burasi. Makinenizin nasil bir sey oldugunu, ne kadar bir sureden bahsetmizi bilmiyoruz.

    2) Listview kullaniyorsunuz. Bu da bir yavaslik nedeni. DataGridView yerine ListView kullanmak icin ozel bir nedeniniz yoksa burada da hiz kazanabilirsiniz.

    Ben kendi makinemde (Ryzen 9 3900XT, 32 Gb RAM, Gen4 NVME) 8000 satili bir excel ornek dosyasi yaratarak denedim, Listview kullanarak formun goruntulenmesi 3.2 - 3.3 saniye. DataGridView ile 0.4 - 0.6 saniye.

    Excel'den veriyi EPPLus ile okudum (Nuget).

    Sub Main
    	Dim pck As ExcelPackage = New ExcelPackage("d:\temp\ExcelOrnek.xlsx")
    	Dim dt = pck.Workbook.Worksheets(0).Tables(0).ToDataTable()
    	ShowData(dt)
    End Sub
    
    Private Sub ShowData(ByVal t As DataTable)
    	Dim f As Form = New Form()
    	Dim lvOrnek As ListView = New ListView With {
    		.Dock = DockStyle.Fill,
    		.View = View.Details
    	}
    	f.Controls.Add(lvOrnek)
    	lvOrnek.LabelEdit = True
    	lvOrnek.AllowColumnReorder = True
    	lvOrnek.FullRowSelect = True
    	lvOrnek.GridLines = True
    
    	For Each c As DataColumn In t.Columns
    		lvOrnek.Columns.Add(c.ColumnName, -2)
    	Next
    
    	f.Show()
    	lvOrnek.Items.Clear()
    
    	For Each r As DataRow In t.Rows
    		Dim ekle As ListViewItem = New ListViewItem()
    		ekle.Text = r(0).ToString()
    
    		For i As Integer = 1 To t.Columns.Count - 1
    			ekle.SubItems.Add(r(i).ToString())
    		Next
    
    		lvOrnek.Items.Add(ekle)
    	Next
    
    	lvOrnek.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)
    End Sub
    

    Listview yerine DataGridView kullanarak:

    Sub Main
    	Dim pck As ExcelPackage = New ExcelPackage("d:\temp\ExcelOrnek.xlsx")
    	Dim dt = pck.Workbook.Worksheets(0).Tables(0).ToDataTable()
    	Dim f As Form = New Form()
    	Dim dgv = New DataGridView With { .Dock = DockStyle.Fill, .DataSource = dt }
    	f.Controls.Add(dgv)
    	f.Show()
    End Sub
    



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.

    27 Mayıs 2022 Cuma 15:53
  • Eksik bilgi için özür dilerim. Sistemim Win10 x64, 8 GB Ram i5 işlemci.

    Süreden kastım 4 ila 5 dakika arası sürüyordu.

    Örneğinizi deneme fırsatım olmadı. Deneyip tekrar dönüş yaparım.

    Teşekkürler ilginiz için

    27 Mayıs 2022 Cuma 18:46
  • Çetin bey, 1. Maddede değindiniz diğer yollar hakkında bikaç örnek ya da link verme şansınız var mı?

    Çalıştığımız sistem sadece excel şeklinde çıktı veriyor. Yani sürekli olarak veri alma ve filtreleme yapmam lazım. Diğer türlü excelin yerleşik fonksiyonlarına çok hakim olmadığımdan çalışmam yeteri kadar verimli olmuyor.

    27 Mayıs 2022 Cuma 18:59
  • Yukarida ornek kodlari verdim ya zaten :) Tek yapmaniz gereken nuget'den epplus alip gerekli importlari eklemek ve dosya adini sizinkiyle degistirmek. Belli sutunlari aliyorsunuz, onun icin ek bir select yapmaniz yeterli.

    Not: Calistiginiz sistem ya cok kotu tasarlanmis, ya da aslinda sadece excel ciktisi vermiyor siz oyle oldugunu saniyorsunuz (mesela insanlar .csv'yi excel dosyasi zannedebiliyor).



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.


    28 Mayıs 2022 Cumartesi 10:03
  • Menude sadece çıktı olarak excele gönder var. Veriler herkese açık değil, excel örneği alındığında da loglanıyoruz. Verileri paket program üretiyor intranet üzerinden. Tek şansım excele gönderip sadece kendi işime yarayacak sütunları çekmek. Nuget yabancı olduğum bi konu. İlk olarak onu öğrenmem lazım. Tekrardan teşekkürler.
    29 Mayıs 2022 Pazar 09:02
  • Isterseniz remotePC ile (veya anydesk, google meet, zoom ...) baglanip 15 dk gostereyim. 


    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.

    29 Mayıs 2022 Pazar 10:37