将Excel文件导入到VB.Net中的现有DataGridView

时间:2019-02-26 07:45:34

标签: excel vb.net datagridview

我的以下代码有问题,该代码冻结并在运行时不执行任何操作。

基础设施: Visual Studio 2017 .NET Framework 4.7.2 操作系统:Windows 7

目标: 我有一个包含3列的DataGridView,我从另一个来源列出了此DataGridView中的一些信息以填充第一行和第二行。

第一行是参数名称,第二行是该参数的当前值。

此过程中未填充第三列,我将填充数据库Excel文件中的第三列,以将参数的当前值与存储在Excel中的数据库值进行比较。这是我的问题开始的地方。

我正在尝试使用以下代码从我正在使用数据库的Excel工作表中填充DataGridView参数值;

某些参数未存储在Excel工作表中,因此实际上,我需要像vlookup这样的函数来映射带有参数名称的数据。

在excel中,A列是我的参数名称,B列是参数的数据库值。

我正在尝试导入此excel,并尝试匹配DataGridView和Excel中的参数名称,如果参数名称相同,则应将Excel参数值写入DataGridView的第三列。

Public Class BuildImportExcel
    Public Shared Sub NewMethod(ByVal dgv As DataGridView)
        Dim ofd As OpenFileDialog = New OpenFileDialog With {
            .Filter = "Excel |*.xlsx",
            .Title = "Import Excel File"
        }
        ofd.ShowDialog()

        Try
            If ofd.FileName IsNot "" Then
                Dim xlApp As New Excel.Application
                If xlApp Is Nothing Then
                    MessageBox.Show("Excel is not properly installed!")
                Else
                    Dim xlBook As Excel.Workbook = xlApp.Workbooks.Open(ofd.FileName)
                    Dim xlSheet As Excel.Worksheet = CType(xlBook.ActiveSheet, Excel.Worksheet)

                    For i = 0 To dgv.Rows.Count
                        If dgv.Rows(i).Cells(0).Value IsNot "" Then
                            Dim look As Boolean = True
                            Dim found As Boolean = False
                            Dim rowLook As Integer = 2
                            Dim rowFound As Integer = 0
                            While look = True
                                If xlSheet.Range("A" & rowLook).Value IsNot "" Then
                                    If xlSheet.Range("A" & rowLook).Text Is dgv.Rows(i).Cells(0).Value Then
                                        found = True
                                        rowFound = rowLook
                                    End If
                                Else
                                    look = False
                                End If
                                rowLook = rowLook + 1
                            End While
                            If found = True Then
                                dgv.Rows(i).Cells(2).Value = xlSheet.Range("B" & rowFound).Text
                            End If
                        End If
                    Next
                    xlApp.Quit()
                    Release(xlSheet)
                    Release(xlBook)
                    Release(xlApp)
                End If
            End If
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
    Private Shared Sub Release(ByVal sender As Object)
        Try
            If sender IsNot Nothing Then
                Marshal.ReleaseComObject(sender)
                sender = Nothing
            End If
        Catch ex As Exception
            sender = Nothing
        End Try
    End Sub

End Class

但是问题是冻结不起作用,我认为参数列表大约有200行,因此导致冻结并尝试使用小部分(如5个参数)进行尝试,并且仍然相同。似乎有问题,我找不到它。

将它们与该方法匹配也是一种逻辑方法,还是您建议使用OLEDB连接之类的方法?

编辑: 我关闭Option Strict,然后将IsNot更改为运算符<>,然后它开始工作,但是我想使用Option Strict On。如何处理此运算符?

1 个答案:

答案 0 :(得分:1)

您正在使此过程变得比原来更加困难。 with pact: result = requests.get(pact.uri + '/posts/1') 循环是一个有问题和成问题的领域。假设很多,在我的测试中,这将导致代码经常冻结。这里的主要问题是代码(某种程度上)遍历了Excel文件中的行。这里的问题是您不知道行数可能是多少!没有对此进行检查,并且代码将在线上失败...

While look = True

到达给定Excel文件的底部时,它将永远找不到匹配项。

另一个问题是线路……

  If xlSheet.Range("A" & rowLook).Value IsNot "" Then

这总是会失败的,永远不会是真的。我的理解...

  

If xlSheet.Range("A" & rowLook).Text Is dgv.Rows(i).Cells(0).Value Then 运算符确定两个对象引用是否引用相同的对象   宾语。但是,它不执行值比较。

鉴于此,我建议您稍微简化一下。最重要的是遍历Excel工作表的“昂贵”循环,如果有很多行,则可能会出现性能问题。当我说很多行时,我的意思是数万行。 200行应该没问题。

如果我们能知道从...返回了工作表中的多少行,那将使事情变得简单。

Is

这基本上是一个Excel Dim xlSheet As Excel.Worksheet = CType(xlBook.ActiveSheet, Excel.Worksheet) ,并且可以通过此Range通过以下方式获得此excel范围中的行数:

Range

现在,我们可以用一个简单的 Dim totalExcelRows = xlSheet.UsedRange.Rows.Count 循环代替它,而不是复杂而有问题的While循环。这将消除一些变量,并将循环索引保持在excel文件的行范围内。

我希望这是有道理的...下面是上面描述的示例。

for