【发布时间】:2016-05-01 15:00:40
【问题描述】:
我在下面处理的这个项目是一张参考卡,它从 excel 文件中提取文本,从同一个搜索文件夹中提取图片。然后通过一个接一个地调用 Subs 直到退出应用程序,该过程被“循环”。通过研究文件并重复该过程,参考卡应该每 10 分钟更新一次。问题是我希望代码打开文件,拉,然后完全关闭文件,然后等待并重复。这样可以在下次更新之前编辑文件。相反,它说它仍在使用中,意思是只读的。即使我关闭应用程序和视觉工作室,它仍然显示仍在使用中。使用 Marshal.ObjectRelease 不起作用。代码启动 Excel 进程,完成代码和发布不起作用。在它第二次循环并创建一个新进程(现在是 2 个 Excel 进程)之后,该版本有效,但仅适用于新进程而不是原始进程,并且每次循环都会继续。
Option Explicit On
Imports System
Imports System.IO
Imports System.Text
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Dim appXL As Excel.Application
Dim wbXl As Excel.Workbook
Dim shXL As Excel.Worksheet
Dim FldPath As String
Dim PartID As String
Dim RefCard As String
Dim timeUpDate As Double
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Dispaly Brembo Logo
picLogo.SizeMode = PictureBoxSizeMode.StretchImage
End Sub
Private Sub Wait()
Threading.Thread.Sleep(600000)
ReferenceCardDataPull()
End Sub
Private Async Sub ReferenceCardDataPull()
'Read File Source with part number ******************
PartID = ("19.N111.10")
' Start Excel and get Application object.
appXL = CreateObject("Excel.Application")
appXL.Visible = False
'Open Reference Card*************************************************************************************
FldPath = ("\\HOMESHARE01\Public\Kaizens\Kaizen 44 - Missing Parts\Reference Cards\Completed Reference Cards by Part Number" & "\" & PartID)
If System.IO.Directory.Exists(FldPath) Then
wbXl = appXL.Workbooks.Open(FldPath & "\" & PartID & ".xlsm")
shXL = wbXl.Worksheets("Sheet1")
' Copys Reference Card Data by Cell To App labels
lblCODE.Text = shXL.Cells(6, 5).Value
lblREV.Text = shXL.Cells(3, 5).Value
lblDate.Text = shXL.Cells(9, 5).Value
lblCustomer.Text = shXL.Cells(3, 1).Value
lblPart.Text = shXL.Cells(6, 1).Value
lblSpindleType.Text = shXL.Cells(9, 1).Value
lblPaintType.Text = shXL.Cells(12, 1).Value
lblDunnageType.Text = shXL.Cells(15, 1).Value
lblPartsLayer.Text = shXL.Cells(3, 3).Value
lblLayers.Text = shXL.Cells(6, 3).Value
lblTotalParts.Text = shXL.Cells(9, 3).Value
lblPackagingInstructs.Text = shXL.Cells(12, 3).Value
'Pulls pictures from designated part folder
If System.IO.File.Exists(FldPath & "\" & "PicSpindle" & PartID & ".JPG") Then
picSpindle.Image = Image.FromFile(FldPath & "\" & "PicSpindle" & PartID & ".JPG")
picSpindle.SizeMode = PictureBoxSizeMode.StretchImage
Else
picSpindle.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicRotorTop" & PartID & ".JPG") Then
picRotorTop.Image = Image.FromFile(FldPath & "\" & "PicRotorTop" & PartID & ".JPG")
picRotorTop.SizeMode = PictureBoxSizeMode.StretchImage
Else
picRotorTop.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicRotorBottom" & PartID & ".JPG") Then
picRotorBottom.Image = Image.FromFile(FldPath & "\" & "PicRotorBottom" & PartID & ".JPG")
picRotorBottom.SizeMode = PictureBoxSizeMode.StretchImage
Else
picRotorBottom.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicDunnageFinal" & PartID & ".JPG") Then
picDunnageFinal.Image = Image.FromFile(FldPath & "\" & "PicDunnageFinal" & PartID & ".JPG")
picDunnageFinal.SizeMode = PictureBoxSizeMode.StretchImage
Else
picDunnageFinal.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicDunnageLayer" & PartID & ".JPG") Then
picDunnageLayer.Image = Image.FromFile(FldPath & "\" & "PicDunnageLayer" & PartID & ".JPG")
picDunnageLayer.SizeMode = PictureBoxSizeMode.StretchImage
Else
picDunnageLayer.SizeMode = PictureBoxSizeMode.StretchImage
End If
' Close objects
shXL = Nothing
wbXl.Close()
appXL.Quit()
appXL = Nothing
Else
lblCODE.Text = ("Error")
lblCODE.ForeColor = Color.Red
lblREV.Text = ("Error")
lblREV.ForeColor = Color.Red
lblDate.Text = ("Error")
lblDate.ForeColor = Color.Red
lblCustomer.Text = ("Error")
lblCustomer.ForeColor = Color.Red
lblPart.Text = ("Error")
lblPart.ForeColor = Color.Red
lblSpindleType.Text = ("Error")
lblSpindleType.ForeColor = Color.Red
lblPaintType.Text = ("Error")
lblPaintType.ForeColor = Color.Red
lblDunnageType.Text = ("Error")
lblDunnageType.ForeColor = Color.Red
Lable49.Text = ("Error")
Lable49.ForeColor = Color.Red
lblLayers.Text = ("Error")
lblLayers.ForeColor = Color.Red
lblTotalParts.Text = ("Error")
lblTotalParts.ForeColor = Color.Red
lblPackagingInstructs.Text = ("Error")
lblPackagingInstructs.ForeColor = Color.Red
lblError.Visible = True
End If
timeUpDate = 599
tmrUpdate.Start()
Application.DoEvents()
Await Task.Run(Sub()
Wait()
End Sub)
ReferenceCardDataPull()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles tmrUpdate.Tick
Dim hms = TimeSpan.FromSeconds(timeUpDate)
Dim m = hms.Minutes.ToString
Dim s = hms.Seconds.ToString
If timeUpDate > 0 Then
timeUpDate -= 1
lblTimer.Text = (m & ":" & s)
Else
tmrUpdate.Stop()
lblTimer.Text = "Updating"
End If
End Sub
End Class
更新代码使用 Marshal.objectrelease
Imports System
Imports System.IO
Imports System.Text
Imports System.Runtime.InteropServices
Imports Excel = Microsoft.Office.Interop.Excel
Imports System.ComponentModel
Public Class Form1
Dim appXL As Excel.Application
'Dim wbXl As Excel.Workbook**** Archive
'Dim shXL As Excel.Worksheet**** Archive
Dim wbXls As Excel.Workbooks
Dim wbXl As Excel.Workbook
Dim shXL As Excel.Worksheet
Dim FldPath As String
Dim PartID As String
Dim RefCard As String
Dim timeUpDate As Double
Dim OpenFolder As Object = CreateObject("shell.application")
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Dispaly Brembo Logo
picLogo.SizeMode = PictureBoxSizeMode.StretchImage
ReferenceCardDataPull()
End Sub
Private Sub Wait()
Threading.Thread.Sleep(10000)
End Sub
Private Async Sub ReferenceCardDataPull()
'Prepare For Load
lblTimer.Text = "Updating"
lblError.Visible = False
'Read File Source with part number ******************
PartID = ("19.N111.10")
' Start Excel and get Application object.
appXL = CreateObject("Excel.Application")
appXL.Visible = False
'Open Reference Card*************************************************************************************
FldPath = ("\\HOMESHARE01\Public\Kaizens\Kaizen 44 - Missing Parts\Reference Cards\Completed Reference Cards by Part Number" & "\" & PartID)
If System.IO.Directory.Exists(FldPath) Then
If System.IO.File.Exists(FldPath & "\" & PartID & ".xlsm") Then
'wbXl = appXL.Workbooks.Open(FldPath & "\" & PartID & ".xlsm")**** Archive
wbXls = appXL.Workbooks
wbXl = wbXls.Open(FldPath & "\" & PartID & ".xlsm")
shXL = wbXl.Worksheets("Sheet1")
' Copys Reference Card Data by Cell To App labels
lblCODE.Text = shXL.Cells(6, 5).Value
lblREV.Text = shXL.Cells(3, 5).Value
lblDate.Text = shXL.Cells(9, 5).Value
lblCustomer.Text = shXL.Cells(3, 1).Value
lblPart.Text = shXL.Cells(6, 1).Value
lblSpindleType.Text = shXL.Cells(9, 1).Value
lblPaintType.Text = shXL.Cells(12, 1).Value
lblDunnageType.Text = shXL.Cells(15, 1).Value
lblPartsLayer.Text = shXL.Cells(3, 3).Value
lblLayers.Text = shXL.Cells(6, 3).Value
lblTotalParts.Text = shXL.Cells(9, 3).Value
lblPackagingInstructs.Text = shXL.Cells(12, 3).Value
Else
lblCODE.Text = ("Error")
lblREV.Text = ("Error")
lblDate.Text = ("Error")
lblCustomer.Text = ("Error")
lblPart.Text = ("Error")
lblSpindleType.Text = ("Error")
lblPaintType.Text = ("Error")
lblDunnageType.Text = ("Error")
Lable49.Text = ("Error")
lblLayers.Text = ("Error")
lblTotalParts.Text = ("Error")
lblPackagingInstructs.Text = ("Error")
lblError.Visible = True
' Close objects**** Archive
' shXL = Nothing**** Archive
' wbXl.Close()**** Archive
'appXL.Quit()**** Archive
'appXL = Nothing**** Archive
End If
Else
'File not found Error
lblCODE.Text = ("Error")
lblREV.Text = ("Error")
lblDate.Text = ("Error")
lblCustomer.Text = ("Error")
lblPart.Text = ("Error")
lblSpindleType.Text = ("Error")
lblPaintType.Text = ("Error")
lblDunnageType.Text = ("Error")
Lable49.Text = ("Error")
lblLayers.Text = ("Error")
lblTotalParts.Text = ("Error")
lblPackagingInstructs.Text = ("Error")
lblError.Visible = True
End If
'Pulls pictures from designated part folder
If System.IO.File.Exists(FldPath & "\" & "PicSpindle" & PartID & ".JPG") Then
picSpindle.Image = Image.FromFile(FldPath & "\" & "PicSpindle" & PartID & ".JPG")
picSpindle.SizeMode = PictureBoxSizeMode.StretchImage
Else
picSpindle.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicRotorTop" & PartID & ".JPG") Then
picRotorTop.Image = Image.FromFile(FldPath & "\" & "PicRotorTop" & PartID & ".JPG")
picRotorTop.SizeMode = PictureBoxSizeMode.StretchImage
Else
picRotorTop.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicRotorBottom" & PartID & ".JPG") Then
picRotorBottom.Image = Image.FromFile(FldPath & "\" & "PicRotorBottom" & PartID & ".JPG")
picRotorBottom.SizeMode = PictureBoxSizeMode.StretchImage
Else
picRotorBottom.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicDunnageFinal" & PartID & ".JPG") Then
picDunnageFinal.Image = Image.FromFile(FldPath & "\" & "PicDunnageFinal" & PartID & ".JPG")
picDunnageFinal.SizeMode = PictureBoxSizeMode.StretchImage
Else
picDunnageFinal.SizeMode = PictureBoxSizeMode.StretchImage
End If
If System.IO.File.Exists(FldPath & "\" & "PicDunnageLayer" & PartID & ".JPG") Then
picDunnageLayer.Image = Image.FromFile(FldPath & "\" & "PicDunnageLayer" & PartID & ".JPG")
picDunnageLayer.SizeMode = PictureBoxSizeMode.StretchImage
Else
picDunnageLayer.SizeMode = PictureBoxSizeMode.StretchImage
End If
' Close objects
wbXl.Close()
wbXls.Close()
appXL.Quit()
'Release Objects
releaseObject(shXL)
releaseObject(wbXl)
releaseObject(wbXl)
releaseObject(wbXls)
releaseObject(appXL)
timeUpDate = 9
tmrUpdate.Start()
Application.DoEvents()
Await Task.Run(Sub()
Wait()
End Sub)
ReferenceCardDataPull()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles tmrUpdate.Tick
Dim hms = TimeSpan.FromSeconds(timeUpDate)
Dim m = hms.Minutes.ToString
Dim s = hms.Seconds.ToString
If timeUpDate > 0 Then
timeUpDate -= 1
lblTimer.Text = (m & ":" & s)
Else
tmrUpdate.Stop()
lblTimer.Text = "Preparing Update"
End If
End Sub
Private Sub releaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
'MsgBox("Final Released obj # " & intRel)
Catch ex As Exception
MsgBox("Error releasing object" & ex.ToString)
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
End Class
【问题讨论】:
-
请看stackoverflow.com/questions/15697282/…那里。看看关于释放对象的例外答案,这可能会有所帮助......
-
@Duraholiday,我不知道为什么我投了反对票,但我可以肯定地告诉你,这就是你问题的答案。看看吧,对你有帮助
-
@ehh 这就是我发布链接的原因,这与我遇到的问题相同......
-
@Codexer 我两天前在工作中遇到了同样的问题,我发布了我写的 PrintExcel 方法。
-
@Codexer,只要明白你为什么投反对票。无论如何,我看看你得到的解决方案,正如你在那里提到的那样,它不起作用。它适用于 Word,但不适用于 Excel。原因是我在下面的解决方案中写的点。工作簿对象未关闭且未释放。查看您的链接和您获得的解决方案。