【发布时间】:2021-09-07 18:11:38
【问题描述】:
简单的担忧:我注意到我必须在此处使用CType 进行转换,即使Cells 已经返回Range。我究竟做错了什么? Cells 是只读的,不带任何参数。好吧,我曾经被这样展示过。
如果我这样做
xlRange = myWorksheet.Cells(Line + 1US, 2US)
错误是
Option Strict On 不允许从 'Object' 到 'Range' 的隐式转换
我想提一下——如果是因为这个原因——我将 Option Infer Off 关闭,这样我就强迫自己总是写下类型。
源代码应将测量值写入 Excel 表中一段时间。
例子:
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
类范围的变量:
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))
【问题讨论】:
-
第二个问题的答案可以在docs.microsoft.com/en-us/dotnet/api/…找到
TimeSpan.ToString("...") -
@Mary 谢谢!
Duration_of_the_runtime.ToString("ddd\:hh\:mm") -
美国价值观的旁注。只需使用整数(Int32)。见stackoverflow.com/questions/530690/net-optimized-int32
-
我假设当你说“
Cells正在返回一个Range”时,你是通过文档还是某种运行时检查?因为错误提示即使返回值的运行时类型是Range,静态类型也是Object。Option Strict On不允许隐式转换,包括来自Object的转换,因此您必须使用CType或DirectCast。 (后者将避免在运行时类型不匹配时尝试查找转换的一些小开销。) -
因此您可以确信将结果转换为
Range会起作用。这种不幸的设计可能与 Excel 自动化对象模型有关,在我的记忆中,由于有很多遗留包袱,使用它并不是最友好的。如果您发现 PITA 的投射量过多,您可以随时转Option Strict Off,我通常不会推荐,但也有例外。 (我想我是在我自己的一些 Excel 自动化代码上这样做的,因为界面的类型很松散。)