很简单的查询及写入,为何等待期间会假死?
程序从一个指定的excel文件中逐个获取人名,然后用这个人名作为条件通过ado.net到数据库中查询匹配的记录数,并将记录数再写入到excel中,系统运行期间,程序假死,直到查询及写入任务全部完成。这是为何?
如何解决?
代码如下(添加了sqlconnection sqlcommand控件各一个)
Imports System.IO
Imports Microsoft.Office.Interop
Imports System.Data
Imports System.Data.SqlClient
Public Class Form1
'添加COM引用,包括:Microsoft.Excel.x.0.Object.Library,Microsoft.Office.x.0.Object.Library
'建议安装正版OFFICE,而且版本在11.0以上(Office2003以上),
'引用以上两个Com后,
'在项目引用栏发现多了Excel、Microsoft.Office.Core,VBIDE三个 Library.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: 这行代码将数据加载到表“CMSManageDataSet.tb_Log”中。您可以根据需要移动或移除它。
Dim xlapp As Excel.Application
Dim xlbook As Excel.Workbook
Dim xlsheet As Excel.Worksheet
Dim xlrang As Excel.Range
Dim xlstr As String
Dim intrownum As Integer
Dim intcolnum As Integer
Dim x As Integer
Dim y1 As Integer
Dim y2 As Integer
Dim w1 As Integer
Dim w2 As Integer
Dim t1 As Date = Now.ToShortDateString
Dim t2 As Date = DateTime.Now.AddDays(-8)
Dim xstr As String
Dim mysqlstr As String
sqlconDTZF.Open()
'Dim mysqlcommand As New SqlCommand()
'上述语句中如果不用new关键字,那么mysqlcommand的commandtext属性无法使用
'上述二个对象的创建需要imports system.data.sqlclient的引用支持
xlapp = CreateObject("excel.application")
xlapp.Visible = False
xlbook = xlapp.Workbooks.Open("c:\1.xls")
xlsheet = xlbook.Worksheets(1)
xlsheet.Activate()
intrownum = xlsheet.UsedRange.Rows.Count
intcolnum = xlsheet.UsedRange.Columns.Count
Me.TextBox1.Text = intrownum
'以下for循环的次数是根据电子表格中姓名的数量(intrownum)来确定的,
'并将姓名从电子表格中取出,作为变量加入到sql语句中
For x = 2 To intrownum
xlrang = xlsheet.Cells(x, 1)
xlstr = xlrang.Value
'MessageBox.Show(xlstr)
'上述语句首先是取出姓名,X从2开始是因为
mysqlstr = "select count(*) from tb_log where describe like '%" + xlstr + "未%'"
mysqlcommand.CommandText = mysqlstr
y1 = mysqlcommand.ExecuteScalar()
xlsheet.Cells(x, 4) = y1
'以上四句语句是查询未命中的记录数,并将结果写入指定单元格
mysqlstr = "select count(*) from tb_log where describe like '%" + xlstr + "正%'"
mysqlcommand.CommandText = mysqlstr
y2 = mysqlcommand.ExecuteScalar()
xlsheet.Cells(x, 3) = y2
'以上四句语句是查询命中的记录数,并将结果写入指定单元格
xlsheet.Cells(x, 2) = y1 + y2
xlsheet.Cells(x, 5) = y2 / (y1 + y2) * 100%
'以上二句语句是计算命中数的百分比,并将结果写入指定单元格
mysqlstr = "select count(*) from tb_log where describe like '%" + xlstr + "正%' and optime<'" + t2.ToString + "'"
mysqlcommand.CommandText = mysqlstr
w1 = mysqlcommand.ExecuteScalar()
xlsheet.Cells(x, 6) = w1
'以上四句语句是查询未命中的记录数,并将结果写入指定单元格
'MessageBox.Show(mysqlstr)
Next
'xlsheet.Cells(1, 1) = Now().ToString
'上面的语句:将当前时间作为值写入EXCEL指定单元格
xlbook.Close(True)
xlapp.Quit()
'以上语句为关闭excel,并在关闭前提示用户是否保存时选择true
Dim i As Integer
Dim proc As Process()
'判断excel进程是否存在
If System.Diagnostics.Process.GetProcessesByName("excel").Length > 0 Then
proc = Process.GetProcessesByName("excel")
'得到名为excel进程个数,全部关闭
For i = 0 To proc.Length - 1
proc(i).Kill()
Next
End If
proc = Nothing
'TextBox2.Text = SqlcomDTZF_COUNT.ExecuteScalar()
sqlconDTZF.Close()
End Sub --------------------编程问答-------------------- 另开线程执行这些操作 --------------------编程问答-------------------- 是查询的数据太多了吧 --------------------编程问答-------------------- 不用线程,执行期间,界面是不会响应的 --------------------编程问答-------------------- --------------------编程问答-------------------- 建议楼主使用多线程解决这个问题。
要知道,设计IO的操作,为了保证界面不卡死,理论上是应该都用新开的线程来进行。界面作为主线程只负责和用户的交互。 --------------------编程问答-------------------- 数据量比较大的循环,建议在循环末尾加个
Application.DoEvent()
试试 --------------------编程问答-------------------- 数据量较大的,Excel模拟写入的操作太过频繁,所以速度慢。
可以试着先将数据存放在数组中,然后一次写入,这样速度就会快许多
补充:.NET技术 , VB.NET