【问题标题】:Can an unbound text box containing a string be set to equal a date(time) field programatically?可以以编程方式将包含字符串的未绑定文本框设置为等于日期(时间)字段吗?
【发布时间】:2020-04-02 22:19:29
【问题描述】:

好的。目标是以编程方式从窗体上的未绑定控件中获取一串数字。为什么?我有一个包含开始时间和结束时间两个控件的表单。这些控件的格式为 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

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

【问题讨论】:

    标签: vba ms-access


    【解决方案1】:

    事实证明,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)
    

    【讨论】:

    • 没说好,但我会尝试澄清为什么我在未绑定控件中使用字符串。因此,我们的想法是有两个未绑定的控件,它们都将收集一个 4 位数的值(可能是一个字符串或也可能是一个日期)......注意,这些控件仅用于收集 mm:hh 格式的时间。然后我想使用这些值通过日期/时间部分函数将数据提供给实际的日期/时间时间字段属性。因此,我将采用未绑定 (mm:hh) 控件值并将其解析到日期/时间字段中,仅用于时间部分(日期也可以从不同的控件中设置)。
    • 然后尝试格式化文本框以仅显示时间。再次,您发现文本框的数据类型是日期时间。因此,填充时间值(甚至作为字符串)将产生实际的日期时间。因此,您可以在这些文本框上使用 timeserial()、hour()、minute() 函数等,或使用从该文本框分配的变量(作为日期类型)
    【解决方案2】:

    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 事件来验证用户输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 2017-09-16
      • 1970-01-01
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多