【问题标题】:Enter date into function without quotes, return date在不带引号的函数中输入日期,返回日期
【发布时间】:2014-05-07 19:13:57
【问题描述】:

我正在尝试编写这种形式的函数:

Function cont(requestdate As Date)
    cont = requestdate
End Function

不幸的是,当我在一个单元格中输入=cont(12/12/2012) 时,我没有找回我的日期。我得到一个非常小的数字,我认为它等于 12 除以 12 除以 2012。我怎样才能得到这个来给我回日期?我不希望用户必须输入=cont("12/12/2012")

我试图用谷歌搜索答案,不幸的是,我没有发现任何有用的信息。请让我知道我的词汇是否正确。

假设我的用户提取了一个包含 3 列 a、b 和 c 的报告。 a 有季初余额,b 有季末余额,c 有名字和姓氏。我希望我的用户输入 d 列:=cont(a1,b1,c1,12/12/2012) 并使其创建类似:

BOQ IS 1200, EOQ IS 1300, NAME IS EDDARD STARK, DATE IS 12/12/2012

所以我们可以将它加载到数据库中。对于第一次缺乏信息,我深表歉意。老实说,这个功能不会为我节省大量时间。我只是想学习 VBA,并认为这将是一个很好的练习......然后我就卡住了。

【问题讨论】:

  • 抱歉,Excel 不能这样工作。它会自动为您计算并将其转换为双精度数。
  • =cont(12/12/2012) 替换为=cont(Date(2012,12,12))=cont(DateValue("12/12/2012"))
  • @simoco 不太容易将其概括为在 UDF 中使用,但...
  • 顺便说一句,这个 UDF 有什么意义?如果您输入单元格12/12/2012,它不会做您想要的(返回日期)吗?
  • 正如 Simoco 提到的,这个 UDF(本身)是多余的。你能发布它将在什么上下文中使用吗?可能还有其他解决方案

标签: vba date excel


【解决方案1】:

很难说你真正想要完成什么。

        Function cont(requestdate As String) As String
            cont = Format(Replace(requestdate, ".", "/"), "'mm_dd_YYYY")
        End Function

此代码将采用 Excel 无法识别为数字的字符串,例如12.12.12 并对其进行格式化(关于我能想到的对这个 UDF 唯一有用的东西)并将其作为字符串(不是数字或日期)返回到格式化为文本的单元格。

您可以随心所欲地处理输入的字符串并格式化返回的字符串 - 只是两者都不能是数字或日期(或 Excel 识别的任何其他内容。)

【讨论】:

  • 谢谢。然而,这给了我同样的问题。当我使用您的代码时, =cont(12/12/2012) 给出 0/000497017 等等。 12/12/2012=1/2012=0.000497017。您的代码切换 .使用 /,但问题仍然存在 2012 年 12 月 12 日存储为双精度而不是字符串。
  • @user3613469 您可以随心所欲地处理输入的字符串并格式化返回的字符串 - 只是两者都不能是数字或日期(或 Excel 识别的任何其他内容。 ) 当您输入“12/12/2012”时,这是 Excel 识别的内容。
【解决方案2】:

没有办法完全做你想做的事。我将尝试解释原因。

您可能会认为,因为您的函数需要 Date 参数,所以这会以某种方式强制或应该强制将 12/12/2012 视为日期。并且它被视为一个日期——但只有它被评估(只有当评估的表达式不能被解释为一个日期,那么你会得到一个错误)。

为什么 Excel 在函数接收它之前评估它?

如果不需要字符串限定符,应用程序怎么可能知道您想要的数据类型,或者您是否想要评估?它不可能知道,所以会有混乱。

也许这是最好的例子。使用你的功能:

=Cont(1/1/0000) 应该会引发错误。

或者考虑一个非常简单的公式:

=1/2

这个公式应该返回.5(双精度)还是January 2(日期)还是应该返回"1/2"(字符串字面量)?最终,它必须做其中之一,并且始终如一地做一件事,而 Excel 在这种情况下要做的一件事就是评估表达式。

TL;DR

您的问题是,不合格的表达式将在通过之前求值,这样做是为了避免混淆或歧义(每个示例)。

【讨论】:

    【解决方案3】:

    这是我在不将日期括在引号中的情况下允许快速将日期输入用户定义函数的方法:

    Function cont(requestdate As Double) As Date
    
        cont = CDate((Mid(Application.Caller.Formula, 7, 10)))
    
    End Function
    

    UDF 调用与 OP 的初始请求一致:

    =cont(12/12/2012)
    

    我相信这种方法可以很好地适应 OP 的更复杂的询问,但建议将日期移到通话的开头:

    =cont(12/12/2012,a1,b1,c1)
    

    我完全希望这种方法可以针对速度和灵活性进行优化。现在从事一个项目,可能需要我进一步深入研究速度部分,但同时它也适合我的需要。如果有什么有用的东西会更新。

    简要说明

    • Application.Caller 返回一个 Range,其中包含调用 UDF 的单元格。 (参见注意事项 #2)
    • Mid 返回从指定长度 (10) 的指定字符数 (7) 开始的字符串的一部分(本例中称为 UDF 的范围中的公式)。
    • CDate 实际上可能不是必需的,但如果可能,会强制将值转换为日期格式。

    注意事项

    1. 这确实需要使用完整的 dd/mm/yyyy(2012 年 1 月 1 日会失败),但仍然可以使用我喜欢的 yyyy/mm/dd 格式以及覆盖 一些 其他分隔符. dd-mm-yyyydd+mm+yyyy 可以,但 dd.mm.yyyy 不行,因为 excel 无法将其识别为有效数字。

    2. 需要额外的工作才能使其作为多单元格数组公式的一部分发挥作用,因为在这种情况下,Application.Caller 返回一个包含所有关联单元格的范围。

    3. 没有错误处理,=cont(123)=cont(derp)(基本上不是dd/mm/yyy)自然会失败。

    免责声明

    这里给那些质疑 UDF 是否明智的人一个简短的说明:我有一个很大的项目网格及其相关任务。在没有参数的情况下,我的 UDF 根据许多项目和任务参数计算截止日期。当包含可选日期时,UDF 返回实际日期与计算日期之间的差值。我使用这个增量来监控和校准我计算出的到期日期。

    所有这些都可以在没有 UDF 的情况下执行,但至少可以说批量输入更具挑战性。

    删除对引号的需要设置了我的数据输入,以便将 =cont( 加载到剪贴板中允许我的左手 F2/ctrl-v/tab 而我的右手在小键盘上狂暴地输入日期而无需频繁地(并且笨拙地)将左手位置移到 shift+'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      相关资源
      最近更新 更多