【问题标题】:How to call VBA function from batch file如何从批处理文件中调用 VBA 函数
【发布时间】:2017-10-27 14:19:42
【问题描述】:

我有一个 .bat 文件,它在我在 cmd 中输入日期后执行一些代码:

test.bat 包含:

 - set /P PWeekday=asofdate:

因为我总是进入前一个工作日,所以我想编写一些代码来做到这一点。但是发现作为批处理脚本的一部分非常困难,我读到在 excel 中创建宏并将值传递到命令行以运行批处理脚本要容易得多。所以我就这样做了:

VBA 中的 PWeekday 函数

Public Function PWeekday() As String

Dim offset Day As Integer

If Weekday(Date) = 1 Then ' Monday

  offsetDay = 3

End If

PWeekDay = Format(Date - offsetDay, "YYYYMMDD")

End Function

问题:

我必须向批处理文件添加什么,以便在我运行它时,它使用来自 vba 函数的 Pweekday 值而不是我的用户输入?

非常感谢您,任何帮助或建议将不胜感激。

【问题讨论】:

  • 您是想处理公共假期/银行假期,还是只想要平淡无奇的工作日?
  • 普通工作日就足够了,上面的 vba sn-p 可以完成这项工作,但我只是不知道如何将其合并到批处理中。谢谢
  • 您可能需要考虑使用 VBScript 而不是 VBA。 VBA 托管在一个host 应用程序中;如果不加载主机 AFAIK,您将无法调用任何 VBA。
  • 我不确定您的意思,您能否就我目前在上面的内容提出建议?我必须用我的函数创建一个 .vbs 文件,然后在我的 .bat 文件中指定文件的路径吗?谢谢

标签: windows vba excel batch-file cmd


【解决方案1】:

虽然您可以在 bat 文件中完成所有这些操作,但我可以理解您为什么要在混合脚本中执行此操作。因此,我没有使用 VBA,而是使用 VBScript 来获得所需的结果

VBScript 代码

Dim AsOfDate
If WeekDay(Date,2) = 1 Then 'WeekDay(Date,2) = 2 to ensure monday as start of week because default of vbs function is sunday
    AsOfDate=DateAdd("d",-3,Date)
Else
    AsOfDate=Date
End If
WScript.Echo DatePart("yyyy",AsOfDate,2) & DatePart("m",AsOfDate,2) & DatePart("d",AsOfDate,2) 'DatePart(xxx,AsOfDate,2) = 2 to ensure monday as start of week

批号

for /f "delims=" %%r in ('cscript //nologo C:\Users\pankaj.jaju\Desktop\Test.vbs') do set result=%%r
echo %result%

【讨论】:

  • 这很完美,正是我想要的——谢谢!
【解决方案2】:

作为批处理脚本的一部分,前一个工作日的计算并不是“非常困难”;它只是有点大:

@echo off
setlocal

REM Reference: http://www.hermetic.ch/cal_stud/jdn.htm#comp

rem Convert the Date in MM/DD/YYYY format to Julian Day Number and get the Day Of Week
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
   set /A "a=(%%a-14)/12, JDN=(1461*(%%c+4800+a))/4+(367*(%%a-2-12*a))/12-(3*((%%c+4900+a)/100))/4+%%b-32075, DOW=(JDN+1)%%7"
)
if %DOW% equ 1 set /A JDN-=3

rem Convert the Julian Day Number back to Date in YYYYMMDD format
set /A "l=JDN+68569,n=(4*l)/146097,l=l-(146097*n+3)/4,i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31,j=(80*l)/2447"
set /A "dd=100+l-(2447*j)/80,l=j/11,mm=100+j+2-(12*l),yyyy=100*(n-49)+i+l"
set "PWeekDay=%yyyy%%mm:~1%%dd:~1%"
echo %PWeekDay%

这是一个简单的方法,当%date% 变量的格式为MM/DD/YYYY 时可以正常工作。如果您的日期格式不同,只需相应地更改set /A 表达式中的%%a%%b 值。如果您希望程序以任何日期格式运行,可以稍作修改以从wmic 命令获取日期。

注意:恐怕我被这个例子中使用的公式弄糊涂了。恕我直言,如果当天不是星期一,则应从当天减去一天;否则使用的日期是同一天,而不是前一天:

if %DOW% equ 1 (set /A JDN-=3) else set /A JDN-=1

【讨论】:

    【解决方案3】:

    我同意 VBA 通常是构建此类自定义函数的更简单工具,但正如其他人指出的那样,它需要 Excel 或其他 VBA 程序的开销来运行该函数。这是可能的,但在这种情况下,您的潜在需求可能有点过头了。

    虽然 VBScript 缺少 VBA 的 Format() 函数,但您可以编写一些非常相似的东西,将在 VBScript 中运行,并使用 Echo 函数将返回结果输出回您的批处理文件。你会看到我只需要对你的函数做很少的改动就可以在 VBScript 中运行它。

    Dim offsetDay
    Dim returnDate
    
    If Weekday(Date) = 1 Then ' Monday
    
      offsetDay = 3
    
    End If
    
    returnDate = Date - offsetDay
    
    ' Build return format with leading zeros
    WScript.Echo DatePart("yyyy", returnDate) & _
        Right("0" & DatePart("m", returnDate),2) & _
        Right("0" & DatePart("d", returnDate),2)
    

    要对其进行测试,您可以双击 VBScript 文件并在消息框中查看返回。当您从批处理文件中调用它时,它会将结果输出到您的批处理程序中。

    这里有几个链接可以帮助您开始从批处理文件中调用 VBScript: pass value from vbscript to batchPass variable from a vbscript to batch file

    希望有帮助!!

    【讨论】:

    • 很好的解释,让我朝着正确的方向前进,谢谢
    【解决方案4】:

    这是使用 PowerShell 的另一种方法。这也通过使用-$weekday - 2 作为偏移量来处理星期日和星期一。

    powershell -NoProfile -Command "$weekday = (Get-Date).DayOfWeek.value__;" ^
        "$offset = -1;" ^
        "if ($weekday -lt 2) { $offset = -$weekday - 2 };" ^
        "((Get-Date).AddDays($offset)).ToString('yyyyMMdd');" >y.txt
    SET /P "PWeekday=" <y.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-01
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      相关资源
      最近更新 更多