这是我第一次使用批处理文件进行编程时,我被要求执行一个能够将.xlsm文件转换为.csv的程序,而无需打开Excel来执行此操作。为此,我使用此.bat文件:
extoc.vbs integration.xlsm integration.csv
Taskkill /IM EXCEL.EXE /F
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
call :StripBlankLines "integration.csv"
goto :eof
:StripBlankLines
For %%x in ("%~1") do set OutF=integration_er.csv
if exist "%OutF%" del "%OutF%"
set FirstLine=1
for /F "usebackq delims=" %%B in (%*) do (
call :TrimWS %%B
if not "!Line!"=="" (
if "!FirstLine!"=="1" (
set FirstLine=0
) else (
>>"%OutF%" echo.
)
call :write !Line!
)
)
goto :eof
:TrimWS
set Line=%*
goto :eof
:write
>>"%OutF%"<NUL set /p Dummy=%*
goto :eof
与.vbs文件一起使用:
if WScript.Arguments.Count < 2 Then
WScript.Echo "Please specify the source and the destination files. Usage: ExcelToCsv <xls/xlsx source file> <csv destination file>"
Wscript.Quit
End If
csv_format = 6
Set objFSO = CreateObject("Scripting.FileSystemObject")
src_file = objFSO.GetAbsolutePathName(Wscript.Arguments.Item(0))
dest_file = objFSO.GetAbsolutePathName(WScript.Arguments.Item(1))
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(src_file)
oBook.SaveAs dest_file, csv_format
oExcel.Quit
oBook.Close False
这里的问题是,作为最终结果,我得到一个巨大的CSV,其中包含原始.xlsm文件中的所有信息,但是除了逗号之外,还有几行只包含逗号,如下所示:
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
虽然我需要这样的东西:
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
data, data, data,, data, data, data, data, data, data
我知道这些逗号来自excel中的空白行,但是我不能使用VBA宏来删除excel中的所有空行,因为它是一张巨大的工作表,每当我尝试这样做时我的电脑都会崩溃。所以,如果有办法通过VBS或BATCH解决这个问题,我真的很高兴!
答案 0 :(得分:1)
:TrimWS
set Line=%*
set "line=%line:,=%"
if defined line set "line=%*"
goto :eof
将,
中的每个line
替换为 nothing 。如果结果是 nothing ,那么line
将是未定义的,即。空。如果它没有用原始值重新加载它。
顺便说一句 - 如果您将FirstLine
设置为没有(set firstline="
)或某些(任何内容,只是没有 >)然后您可以使用if defined firstline
检测其当前状态,这样您就不需要delayedexpansion
。
(重写)
@echo off
SETLOCAL
call :StripBlankLines "integration.csv"
goto :eof
:StripBlankLines
For %%x in ("%~1") do set OutF=integration_er.csv
if exist "%OutF%" del "%OutF%"
set FirstLine=1
for /F "usebackq delims=" %%B in (%*) do (
call :TrimWS %%B
if defined line (
if defined firstline (
set "FirstLine="
) else (
>>"%OutF%" echo.
)
call :write %%B
)
)
goto :eof
:TrimWS
set Line=%*
set "line=%line:,=%"
goto :eof
:write
>>"%OutF%"<NUL set /p Dummy=%*
goto :eof
由于line
将包含与%%B
相同的内容,因此您可以使用%%B
提供它不包含逗号。因此,您可以将%%B
发送到:trimws
例程,line
将设置为 nothing (在所有逗号的情况下)或 (任何东西)否则。
然后,您可以简单地解释line
被定义或不通过%%B
例程输出:write
,因为:write
只会在%%B
时调用不包含所有逗号,但也不是空的(for/f
会处理它)。
在开始时将firstline
设置为某些内容意味着if defined firstline
最初为真,因此您将其设置为 nothing ,之后{{1将是假的。
语法if defined firstline
(其中value可能为空)用于确保任何杂散尾随空格不包含在分配的值中。
SET "var=value"
应该保留,以便setlocal
环境不会在批处理例程运行时累积值。它确保在例程终止时丢弃对环境变量所做的任何更改
答案 1 :(得分:1)
除非我误解,为什么不只使用一行:
FindStr "[^,]" "integration.csv">"integration_er.csv"