我目前正在制作索引程序。我最近在我的正则表达式中添加了一个搜索文件的方法来检测同一文件中正则表达式的重复项。
问题是我得到了:
在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。确保您的Main函数标记了STAThreadAttribute。
当我调用我的导出函数时,会将重复项写入文件。但是我在程序的其他部分多次使用导出函数,之前我从未遇到过这个问题。
简而言之我所做的是:
FormStats.vb :
1.1。正则表达式搜索BackGroundWorker()
1.2。存储重复项(如果有)
1.3。致电BackGroundWorker_RunWorkerCompleted
至ExportDoublon()
FileHandler.vb
2.1。致电WriteDoublon()
至exportToWord()
Exporter.vb
3.1。 exportToWord()
出现错误的行:
Clipboard.SetText(table)
从 FileHandler.vb :
调用类的方式Public Sub WriteDoublon(ByVal CurrentDoub As List(Of Doublon))
Dim dgv As New DataGridView
dgv.Columns.Add("Name", "Name")
dgv.Columns.Add("Fiche", "Fiche")
For Each doublee As Doublon In CurrentDoub
dgv.Rows.Add(doublee.Name, doublee.Ficher)
dgv.Rows.Add("**********", "**********")
Next
Dim exp As New Exporter
Dim prog As New ProgressBar
exp.exportToWord(dgv, AppDomain.CurrentDomain.BaseDirectory & "Exports\Doublon.docx", prog)
End Sub
FileHandler.WriteDoublon()被称为 FormStats.vb 的地方:
Public Sub ExportDoublon()
Dim fl As New FileHandler
fl.WriteDoublon(Doub)
End Sub
出现错误的类 Exporter.vb :
Public Sub exportToWord(ByVal dgv As DataGridView, ByVal pather As String, ByVal progresser As ProgressBar)
Dim oWord As Word.Application = DirectCast(CreateObject("Word.Application"), Word.Application)
Dim oDoc As Word.Document = oWord.Documents.Add()
oWord.Visible = False
Dim headers = (From ch In dgv.Columns
Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell)
Select header.Value).ToArray()
Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)
Dim items() = (From r In dgv.Rows
Let row = DirectCast(r, DataGridViewRow)
Where Not row.IsNewRow
Select (From cell In row.Cells
Let c = DirectCast(cell, DataGridViewCell)
Select c.Value).ToArray()).ToArray()
Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
Dim i As Integer = 0
For Each a In items
Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
table &= String.Join(vbTab, t) & Environment.NewLine
progresser.Value = i * 100 / items.Count
i = i + 1
Next
table = table.TrimEnd(CChar(Environment.NewLine))
'--ERROR HERE
Clipboard.SetText(table)
'#############
Dim oTable As Word.Table = oDoc.Tables.Add(oDoc.Bookmarks.Item("\endofdoc").Range, items.Count + 1, headers.Count)
oTable.Range.Paste()
'make the first row bold, fs 14 + change textcolor
oTable.Rows.Item(1).Range.Font.Bold = &H98967E
oTable.Rows.Item(1).Range.Font.Size = 14
oTable.Rows.Item(1).Range.Font.Color = Word.WdColor.wdColorWhite
'change backcolor of first row
oTable.Rows.Item(1).Range.Shading.Texture = Word.WdTextureIndex.wdTextureNone
oTable.Rows.Item(1).Alignment = Word.WdAlignmentTabAlignment.wdCenter
oTable.Rows.Item(1).Range.Shading.ForegroundPatternColor = Word.WdColor.wdColorAutomatic
oTable.Rows.Item(1).Range.Shading.BackgroundPatternColor = Word.WdColor.wdColorPaleBlue
'set table borders
With oTable.Range.Tables(1)
With .Borders(Word.WdBorderType.wdBorderLeft)
.LineStyle = Word.WdLineStyle.wdLineStyleSingle
.LineWidth = Word.WdLineWidth.wdLineWidth100pt
.Color = Word.WdColor.wdColorAutomatic
End With
With .Borders(Word.WdBorderType.wdBorderRight)
.LineStyle = Word.WdLineStyle.wdLineStyleSingle
.LineWidth = Word.WdLineWidth.wdLineWidth100pt
.Color = Word.WdColor.wdColorAutomatic
End With
With .Borders(Word.WdBorderType.wdBorderTop)
.LineStyle = Word.WdLineStyle.wdLineStyleSingle
.LineWidth = Word.WdLineWidth.wdLineWidth100pt
.Color = Word.WdColor.wdColorAutomatic
End With
With .Borders(Word.WdBorderType.wdBorderBottom)
.LineStyle = Word.WdLineStyle.wdLineStyleSingle
.LineWidth = Word.WdLineWidth.wdLineWidth100pt
.Color = Word.WdColor.wdColorAutomatic
End With
With .Borders(Word.WdBorderType.wdBorderHorizontal)
.LineStyle = Word.WdLineStyle.wdLineStyleSingle
.LineWidth = Word.WdLineWidth.wdLineWidth050pt
.Color = Word.WdColor.wdColorAutomatic
End With
With .Borders(Word.WdBorderType.wdBorderVertical)
.LineStyle = Word.WdLineStyle.wdLineStyleSingle
.LineWidth = Word.WdLineWidth.wdLineWidth050pt
.Color = Word.WdColor.wdColorAutomatic
End With
.Borders(Word.WdBorderType.wdBorderDiagonalDown).LineStyle = Word.WdLineStyle.wdLineStyleNone
.Borders(Word.WdBorderType.wdBorderDiagonalUp).LineStyle = Word.WdLineStyle.wdLineStyleNone
.Borders.Shadow = False
End With
oDoc.SaveAs2(pather)
oDoc.Close()
oDoc = Nothing
oWord.Quit()
oWord = Nothing
GC.Collect()
GC.WaitForFullGCComplete()
End Sub
答案 0 :(得分:2)
您对exportToWord
的调用显然是在配置为Threading.ApartmentState.MTA
的线程上运行(后台工作线程为Threading.ApartmentState.MTA
)。通常当您访问此方法的控件执行datagridview时,您将收到Cross-thread operation not valid
错误。但是,此检查仅针对需要控件的Handle
属性的此类访问运行;在这种情况下,您正在访问dgv
中未触发此检查的数据信息。
如果将以下无意义的语句添加到exportToWord
的开头,则应该抛出错误。
Dim handle As IntPtr = dgv.Handle
必须从Clipboard
线程访问Threading.ApartmentState.STA
,并且UI线程就是这样一个线程。执行此操作的正确方法是在UI线程上使用Invoke
方法Me
是Form实例:
Me.Invoke(New Action(Of DataGridView, String, ProgressBar)(AddressOf exp.exportToWord), New Object(){dgv, AppDomain.CurrentDomain.BaseDirectory & "Exports\Doublon.docx", prog})
与当前的
相比exp.exportToWord(dgv, AppDomain.CurrentDomain.BaseDirectory & "Exports\Doublon.docx", prog)