0

好吧。目标是以编程方式从窗体上的未绑定控件中获取一串数字。为什么?我有一个包含开始时间和结束时间两个控件的表单。这些控件的格式为 dd/mm/yyyy hh:dd。最终用户抱怨他们讨厌花时间在单个字段中输入日期和时间,特别是考虑到旧表单(一个糟糕的 Excel 电子表格,用户可以输入他们想输入的任何内容),只允许他们输入4 位时间。我正在尝试复制这种体验,但正如我们所知,日期和时间都包含在 Access 中的一个字段中。

这个想法是使用单独的未绑定控件为日期/时间字段提供字符串中的值。例如,一个控件将被标记为“开始时间”,并将接受 4 个数字,输入掩码为 99:99。在更新表单之前,我想从控件传递字符串不幸的是,我没有代码,但我会尝试在这里构建伪代码:

类级模块

Private Sub Form_BeforeUpdate(Cancel As Integer)

strStartTime as String
strFinishTime as String
strDate as String
rstDailyLog as recordset

Set rstDailylog = CurrentDb.OpenRecordset ("Daily Log" dbOpenDynaset)

'assign variables to unbound controls on form
strStartTime = Me![Start Time]
strFinishTime = Me![Finish Time]

'Here, I assume I begin parsing my string to the date/time field

'function to edit send the string to the actual date/time field
'Basically, copied from Microsoft Docs
Sub EditName(rstCovertString As Recordset, strStart As String, strFinish As String)

With rstConvertString
.Edit
![Start Time] = strStart
![Finish Time] = strFinish
.Update
.Bookmark = .LastModified
End With

这样做有什么影响?例如,如果绑定的表单显示一条具有未绑定值的记录,该记录将如何显示所需的数据?在构建此代码时,我才意识到保存日期/时间的字段是日期/时间数据类型?现在我真的很困惑。如果它们是不同的数据类型,我什至可以将我的开始/结束变量作为字符串发送到该控件吗?

4

2 回答 2

0

Access 通常会将具有日期/时间结构的字符串识别为日期/时间值。可以使用 CDate() 函数来确定或使用 # 分隔符。

在 VBA 编辑器即时窗口中进行这些测试。

?IsDate("1/1/2020 14:50")

?IsDate(CDate("1/1/2020 14:50"))

?IsDate(#1/1/2020 14:50#)

?IsDate("1/1/2020" & " " & "14:50")

全部返回 True。

如果要显示保存的日期/时间,请将文本框绑定到该字段。如果您不希望用户在其中进行编辑,请锁定该控件。然后使用 VBA 保存在未绑定文本框中所做的任何编辑。我推荐使用 AfterUpdate 事件来保存代码。使用 BeforeUpate 事件来验证用户输入。

于 2020-04-02T23:27:22.920 回答
0

事实证明,Access 为您完成了数据类型转换的 TRUCKLOAD。

当文本框控件绑定到基础表时,该文本框将返回日期时间数据类型。即使您在字符串中填充 - 它也会在幕后转换为日期时间数据类型。

文本也是如此,或者如果控件绑定到一个数字。(同样,这里实际上发生了数据类型强制。但是,VBA 在这方面相当宽容。

因此,大多数时候您不会注意到这个问题。

但是,当文本框未绑定到基础表时,该文本框的数据类型会更加松散。

因此,将未绑定文本框的格式设置为日期格式。如果这样做,那么即使将字符串值分配给文本框也会导致访问将字符串转换为日期时间。实际上,您的代码仍应从该表中获取数据,如果您不直接将日期列分配给文本框?

那么,然后将字符串格式化为美国格式。例如:

me.MyStartDate = format(dtValue, "MM/DD/YYYY")

或者

me.MyStartDate = format(dtValue, "YYYY-MM-DD")

您会发现,即使您的日期格式与上面的不同(比如基于您的计算机区域设置),Access 也会将上面的日期格式转换为内部日期格式,然后显示您的区域设置是什么,而不考虑上述内容。

因此,您的显示可能是:DD/MM/YYYY(第一天)

但是,这样做:

me.MyStartDate = dtvalue

或者

me.MyStartDate = format(dtValue,"YYYY-MM-DD")

将工作。

因此,如果可能,请勿将表中的日期时间值转换为字符串以避免这样做。因此,您只需将该实际日期时间值直接分配给文本框。只要 Access 看到并知道文本框具有日期格式,它就会假定并使用该文本框作为日期时间数据类型。

仅当您将未绑定的文本框设置为具有某种日期格式时,上述内容才有效。一旦您告诉访问该文本框是一个日期类型的文本框,那么直接从表中分配日期值(不转换为字符串)是您的最佳解决方案。

如前所述,对于绑定的文本框,文本框将采用正确的数据类型——即使您没有格式化文本框。

同样的上述技巧也适用于数字格式。因此为文本框设置数字格式将导致该文本框不是字符串/文本类型,而是实际数字。

因此,您可以使用格式化选项将未绑定的文本框强制/设置为给定的数据类型。完成此操作后,您就不需要格式化表格中的数据,实际上只需将实际日期值推入文本框即可。因此,您现在可以(并且应该)为文本框设置任何类型的日期格式 - 即使设置与您的计算机(和用户)一时兴起选择的实际日期格式完全相反。

换句话说,如果你这样做对吗?然后您不必关心,甚至不必知道任何给定计算机上的日期格式设置,您的代码将始终有效。

在我这里的所有建议中?

如果可能,将实际日期值分配给文本框,并且不要格式化字符串。这将允许您为文本框设置任何类型的日期/时间格式。将文本框定义/设置为日期格式后,它就是日期时间事物和数据类型。因此,您不应该要求从表格数据进行任何转换来设置/填写文本框。

编辑

你有:

'assign variables to unbound controls on form
strStartTime = Me![Start Time]
strFinishTime = Me![Finish Time]

不!- 将上述两个变量声明为日期,而不是字符串。

dim dtStartTime     as date
dim dtFinishTime    as date

现在:

dtStartTime = Me![Start Time]
dtFinishTime = Me![Finish Time]

'在这里,我假设我开始将我的字符串解析为日期/时间字段

不,不要解析。您将数据作为内部日期时间。如何显示此数据取决于您或用户的区域设置。作为开发者,它是一个日期类型和一个日期“东西”。不要转换成字符串!!!

'function to edit send the string to the actual date/time field
'Basically, copied from Microsoft Docs

Sub EditName(rstCovertString As Dao.Recordset, dtStart As Date, _
    dtFinish As date)
于 2020-04-03T01:42:06.040 回答