为什么我必须在这里转换'Cells'?
Why do I have to convert ‘Cells’ here?
小问题:我注意到我必须在此处使用 CType
进行转换,即使 Cells
已经返回 Range
。我究竟做错了什么? Cells
是只读的,不接受任何参数。好吧,我曾经被这样展示过。
如果我这样做
xlRange = myWorksheet.Cells(Line + 1US, 2US)
错误是
Option Strict On disallows implicit conversions from 'Object' to 'Range'
我想提一提——如果是因为这个原因的话——我关闭了 Option Infer Off,这样我就可以强迫自己始终写下类型。
源代码应该在Excelsheet中写入一段时间的测量值。
示例:
A B C
1 07.09.2021 08:00 25,0
2 12:00 30,0
3 16:00 35,0
4 08.09.2021 08:00 26,0
5 12:00 28,0
6 16:00 26,0
class-范围变量:
Private Time_of_the_program_start As Date
Private Duration_of_the_runtime As TimeSpan
Private xlApp As Excel.Application
Private myWorkbook As Excel.Workbook
Private running As Boolean = False
Private Line As UInt16 = 0US
Private ReadOnly Deu As New System.Globalization.CultureInfo("de-DE")
running
在按钮过程中设置为 True。
Private Function read_and_write_data(ByVal file_path As String) As Boolean
xlApp = New Excel.Application With {
.Visible = True
}
myWorkbook = xlApp.Workbooks.Add()
Dim myWorksheet As Excel.Worksheet = CType(myWorkbook.Sheets("Tabelle1"), Excel.Worksheet)
Dim xlRange As Excel.Range
Dim Temperatur As Single
While running
Duration_of_the_runtime = Date.Now - Time_of_the_program_start
If Duration_of_the_runtime.Days = 365 Then Exit While
Me.Invoke(Sub() Label_Duration.Text =
Duration_of_the_runtime.Days.ToString(Deu).PadLeft(3, "0"c) & ":" &
Duration_of_the_runtime.Hours.ToString(Deu).PadLeft(2, "0"c) & ":" &
Duration_of_the_runtime.Minutes.ToString(Deu).PadLeft(2, "0"c))
'System.Threading.Thread.Sleep(10000)
'myWorksheet.Cells(Line, column)
'–––––––––––––––––––––––––––––––––––––––
'Spalte A: Datum
'–––––––––––––––––––––––––––––––––––––––
xlRange = CType(myWorksheet.Cells(Line + 1US, 1US), Excel.Range)
xlRange.Value = Date.Now.ToString("d", Deu)
'–––––––––––––––––––––––––––––––––––––––
'Spalte B: Uhrzeiten
'Spalte C: Messwerte
'–––––––––––––––––––––––––––––––––––––––
Temperatur = Get_Temperature_from_Pt100()
xlRange = CType(myWorksheet.Cells(Line + 1US, 2US), Excel.Range)
xlRange.Value = Date.Now.ToString("t", Deu)
xlRange = CType(myWorksheet.Cells(Line + 1US, 3US), Excel.Range)
xlRange.Value = Temperatur
'‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
Temperatur = Get_Temperature_from_Pt100()
xlRange = CType(myWorksheet.Cells(Line + 2US, 2US), Excel.Range)
xlRange.Value = Date.Now.ToString("t", Deu)
xlRange = CType(myWorksheet.Cells(Line + 2US, 3US), Excel.Range)
xlRange.Value = Temperatur
'‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
Temperatur = Get_Temperature_from_Pt100()
xlRange = CType(myWorksheet.Cells(Line + 3US, 2US), Excel.Range)
xlRange.Value = Date.Now.ToString("t", Deu)
xlRange = CType(myWorksheet.Cells(Line + 3US, 3US), Excel.Range)
xlRange.Value = Temperatur
'–––––––––––––––––––––––––––––––––––––––
'inkrementieren
'–––––––––––––––––––––––––––––––––––––––
Line += 3US
End While
myWorksheet.SaveAs(file_path, Excel.XlFileFormat.xlWorkbookDefault)
myWorkbook.Close()
xlApp.Quit()
If myWorksheet IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorksheet)
If myWorkbook IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorkbook)
If xlApp IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
xlApp = Nothing
myWorkbook = Nothing
myWorksheet = Nothing
Return True
End Function
顺便说一句:有没有更优雅的解决方案?
Me.Invoke(Sub() Label_Duration.Text =
Duration_of_the_runtime.Days.ToString(Deu).PadLeft(3, "0"c) & ":" &
Duration_of_the_runtime.Hours.ToString(Deu).PadLeft(2, "0"c) & ":" &
Duration_of_the_runtime.Minutes.ToString(Deu).PadLeft(2, "0"c))
对于您的主要问题,不,您没有做错任何事情,这正是 Excel 自动化界面的行为方式。具体来说,集合类型都是经典的 VBA Collection
(或等效的功能),这意味着索引访问 returns 和 Object
而不是强类型的东西。
正如您所指出的,如果您尝试在 Option Strict On
上下文中使用它,则必须强制转换结果。我自己的互操作代码有一堆收集项访问,到处都是 DirectCast(.Rows(2), Excel.Range)...
之类的东西
小问题:我注意到我必须在此处使用 CType
进行转换,即使 Cells
已经返回 Range
。我究竟做错了什么? Cells
是只读的,不接受任何参数。好吧,我曾经被这样展示过。
如果我这样做
xlRange = myWorksheet.Cells(Line + 1US, 2US)
错误是
Option Strict On disallows implicit conversions from 'Object' to 'Range'
我想提一提——如果是因为这个原因的话——我关闭了 Option Infer Off,这样我就可以强迫自己始终写下类型。
源代码应该在Excelsheet中写入一段时间的测量值。
示例:
A B C
1 07.09.2021 08:00 25,0
2 12:00 30,0
3 16:00 35,0
4 08.09.2021 08:00 26,0
5 12:00 28,0
6 16:00 26,0
class-范围变量:
Private Time_of_the_program_start As Date
Private Duration_of_the_runtime As TimeSpan
Private xlApp As Excel.Application
Private myWorkbook As Excel.Workbook
Private running As Boolean = False
Private Line As UInt16 = 0US
Private ReadOnly Deu As New System.Globalization.CultureInfo("de-DE")
running
在按钮过程中设置为 True。
Private Function read_and_write_data(ByVal file_path As String) As Boolean
xlApp = New Excel.Application With {
.Visible = True
}
myWorkbook = xlApp.Workbooks.Add()
Dim myWorksheet As Excel.Worksheet = CType(myWorkbook.Sheets("Tabelle1"), Excel.Worksheet)
Dim xlRange As Excel.Range
Dim Temperatur As Single
While running
Duration_of_the_runtime = Date.Now - Time_of_the_program_start
If Duration_of_the_runtime.Days = 365 Then Exit While
Me.Invoke(Sub() Label_Duration.Text =
Duration_of_the_runtime.Days.ToString(Deu).PadLeft(3, "0"c) & ":" &
Duration_of_the_runtime.Hours.ToString(Deu).PadLeft(2, "0"c) & ":" &
Duration_of_the_runtime.Minutes.ToString(Deu).PadLeft(2, "0"c))
'System.Threading.Thread.Sleep(10000)
'myWorksheet.Cells(Line, column)
'–––––––––––––––––––––––––––––––––––––––
'Spalte A: Datum
'–––––––––––––––––––––––––––––––––––––––
xlRange = CType(myWorksheet.Cells(Line + 1US, 1US), Excel.Range)
xlRange.Value = Date.Now.ToString("d", Deu)
'–––––––––––––––––––––––––––––––––––––––
'Spalte B: Uhrzeiten
'Spalte C: Messwerte
'–––––––––––––––––––––––––––––––––––––––
Temperatur = Get_Temperature_from_Pt100()
xlRange = CType(myWorksheet.Cells(Line + 1US, 2US), Excel.Range)
xlRange.Value = Date.Now.ToString("t", Deu)
xlRange = CType(myWorksheet.Cells(Line + 1US, 3US), Excel.Range)
xlRange.Value = Temperatur
'‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
Temperatur = Get_Temperature_from_Pt100()
xlRange = CType(myWorksheet.Cells(Line + 2US, 2US), Excel.Range)
xlRange.Value = Date.Now.ToString("t", Deu)
xlRange = CType(myWorksheet.Cells(Line + 2US, 3US), Excel.Range)
xlRange.Value = Temperatur
'‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
Temperatur = Get_Temperature_from_Pt100()
xlRange = CType(myWorksheet.Cells(Line + 3US, 2US), Excel.Range)
xlRange.Value = Date.Now.ToString("t", Deu)
xlRange = CType(myWorksheet.Cells(Line + 3US, 3US), Excel.Range)
xlRange.Value = Temperatur
'–––––––––––––––––––––––––––––––––––––––
'inkrementieren
'–––––––––––––––––––––––––––––––––––––––
Line += 3US
End While
myWorksheet.SaveAs(file_path, Excel.XlFileFormat.xlWorkbookDefault)
myWorkbook.Close()
xlApp.Quit()
If myWorksheet IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorksheet)
If myWorkbook IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorkbook)
If xlApp IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
xlApp = Nothing
myWorkbook = Nothing
myWorksheet = Nothing
Return True
End Function
顺便说一句:有没有更优雅的解决方案?
Me.Invoke(Sub() Label_Duration.Text =
Duration_of_the_runtime.Days.ToString(Deu).PadLeft(3, "0"c) & ":" &
Duration_of_the_runtime.Hours.ToString(Deu).PadLeft(2, "0"c) & ":" &
Duration_of_the_runtime.Minutes.ToString(Deu).PadLeft(2, "0"c))
对于您的主要问题,不,您没有做错任何事情,这正是 Excel 自动化界面的行为方式。具体来说,集合类型都是经典的 VBA Collection
(或等效的功能),这意味着索引访问 returns 和 Object
而不是强类型的东西。
正如您所指出的,如果您尝试在 Option Strict On
上下文中使用它,则必须强制转换结果。我自己的互操作代码有一堆收集项访问,到处都是 DirectCast(.Rows(2), Excel.Range)...