Board logo

标题: 【练习-033】计算并重写xls文件 [打印本页]

作者: batman    时间: 2008-12-13 10:10     标题: 【练习-033】计算并重写xls文件

出题目的:
       通过解题熟练掌握数值计算的技巧以及重写文件的技巧
加分原则:
       1、完美代码加分15分
       2、思路独特基分5分
       2、代码高效基分4分
       3、代码简洁基分3分
       4、代码通用基分2分
       5、无临时文件基分1分
题目如下:
       有一test.xls文件,原文件及内容如下

链接: https://pan.baidu.com/s/12E6O0w67T1_0MPO-mS2lTQ?pwd=bsk7

      要求通过批处理计算表中各人的工资总和(结果保留两位小数,填写在total后的空格里),并改写test.xls如下图

相关说明:
       1、本题说难不难说容易却不是那么简单,在数值计算上有很多要考虑的问题,大家细心应答了。
       2、暂请版主们不要贴代码,但可以跟贴做提示和指导。
作者: pusofalse    时间: 2008-12-13 16:04

可否先把小数点向后推几位先变成整数,对整数计算完之后再转换为小数呢?~
作者: batman    时间: 2008-12-13 21:54

回二楼这样的方法不是不行,但不通用,如不知道小数后有几位数呢?
作者: batman    时间: 2008-12-13 22:44

提示:用delims来处理小数。

[ 本帖最后由 batman 于 2008-12-13 22:49 编辑 ]
作者: semiuel    时间: 2008-12-13 23:11

刚看到了batman贴在4楼的答案.
然后试了一下,输出答案跟题目中图2的不一样.

稍微修改了一下,可以做到显示一样的.



刚又试了一下,正确的代码贴到这里,也会变成错的.
里面有三个地方需要把空格换成TAB键.

[ 本帖最后由 semiuel 于 2008-12-13 23:18 编辑 ]
作者: batman    时间: 2008-12-14 10:23

回5楼:是的,论坛程序处理不了tab,会将tab默认为空格,原来在cn-dos也是这样的,
不知道为什么一直解决不了这个问题。同时提示大家写入xls文件时各列之间应用tab格
开。。。
作者: shqf    时间: 2008-12-14 10:35

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "skip=1 tokens=1,2,3 delims=        " %%a in (test.xls) do (
  3.   if not defined flag >test.xls echo job        money
  4.   set flag=1
  5.   if "%%b"=="total" (
  6.     >>test.xls echo %%a:%%b        !total:~0,-2!.!total:~-2!
  7.     set total=0) else (
  8.     >>test.xls echo %%b        %%c
  9.     call :count %%c
  10.   )
  11. )
  12. pause
  13. set flag=&set total=&set money=
  14. exit
  15. :count
  16. set money=%1
  17. if "%money:~-3,1%"=="." (set money=%money:.=%) else (
  18.   if "%money:~-2,1%"=="." (set money=%money:.=%0) else (
  19.     set money=%money%00
  20.   )
  21. )
  22. set /a total=%total%+%money%
  23. goto :eof
复制代码
注:delims是以TAB来分开提取的,echo句中也是TAB来分开的

[ 本帖最后由 shqf 于 2008-12-14 10:36 编辑 ]
作者: batman    时间: 2008-12-14 10:42

楼上的兄弟还请注意代码的书写规范,分清层次,切不可写在一堆,同时代码还可简化。

[ 本帖最后由 batman 于 2008-12-14 10:45 编辑 ]
作者: shqf    时间: 2008-12-14 15:18

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "skip=1 tokens=1,2,3 delims= " %%a in (test.xls) do (
  3.   if not defined flag >test.xls echo job money
  4.   set flag=1
  5.   if "%%b"=="total" (
  6.     >>test.xls echo %%a:%%b !total:~0,-5!.!total:~-5!
  7.     set total=0) else (
  8.     >>test.xls echo %%b %%c
  9.     call :count %%c
  10.     set /a total=!total!+!money!
  11.   )
  12. )
  13. test.xls
  14. exit
  15. :count
  16. for /f "tokens=1,2 delims=." %%i in ("%1") do (
  17.   set money=%%j00000
  18.   set money=!money:~0,5!
  19.   set money=%%i!money!
  20. )
  21. goto :eof
复制代码
小数计算部分略作改善,5位小数内可行。其他地方不知如何再精简了。
作者: batman    时间: 2008-12-14 22:10

此题难道就这么难吗?技术组的也没看见几个来接招的!贴出本人的解,大家测试时请将标注为[TAB]的地方改为制表符:

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1-3" %%a in ('type test.xls') do (
  3.      if not defined flag (
  4.        echo %%b[TAB]%%c>test.xls&set "flag=a"
  5.        ) else (
  6.        if "%%c" neq "" (
  7.          for /f "tokens=1,2 delims=." %%i in ("%%c") do (
  8.               set "a=%%i"&set "b=%%j00"&set "+=+"
  9.               if "!a:~,1!" equ "-" set "+=-"
  10.               set /a num1!+!=!a:-=!,num2!+!=1!b:~,2!%%100
  11.               if !num2! geq 100 set /a num2-=100,num1+=1
  12.               if !num2! lss 0 set /a num2+=100,num1-=1
  13.               if !num2! lss 10 set "num2=0!num2!"
  14.          )
  15.          echo %%b[TAB]%%c>>test.xls
  16.          ) else (
  17.          echo %%a:%%b[TAB]!num1!.!num2!>>test.xls&set /a num1=0,num2=0
  18.       )
  19.     )
  20. )
复制代码



[ 本帖最后由 batman 于 2008-12-16 17:24 编辑 ]
作者: pusofalse    时间: 2008-12-15 00:04

来一个不通用的,先化为整数~
  1. @Echo Off & setlocal EnableDelayedExpansion
  2. Echo Job        Money>tmp.xls
  3. For /F "skip=1 tokens=1,2*" %%a in (test.xls) do (
  4.       If "%%c" neq "" (
  5.           set "sep="
  6.           Echo %%b[tab]%%c
  7.           set "num=%%c000" & set "num=!num:.=!"
  8.           If "!num:~,1!" equ "-" (set "sep=-" &set "num=!num:-=!")
  9.           set "num=!sep!!num:~,4!"
  10.           set /a _%%a += num
  11.           ) else (
  12.           Echo %%a:total[tab]!_%%a:~0,-2!.!_%%a:~2!
  13.      )
  14. )>>tmp.xls
复制代码

[ 本帖最后由 pusofalse 于 2008-12-15 00:06 编辑 ]
作者: batman    时间: 2008-12-15 08:25

本人认为在数值加减计算上用delims=.将数值分为两个部分来计算比较合适,但在数值乘除计算上还是将数值先化为整数来计算再化为小数较为合适。
作者: shqf    时间: 2008-12-15 19:24

二位版主的代码还真简洁,又一次学习了。
作者: terse    时间: 2008-12-15 23:17

学习了 先计算位数  这样小数可以不考虑其位数
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1-3 delims=        " %%a in ('type test.xls') do (
  3.   if not defined flag (
  4.     echo %%b                %%c>test.xls&set "flag=a"
  5.      ) else (
  6.        if "%%c"=="" (
  7.        for /l %%d in (1 1 !n!) do set mn=!mn!0
  8.          for %%d in (!var1!) do (
  9.              set/a t+=1
  10.              set var2=%%d!mn!
  11.              call set var2=%%var2:~,!n!%%
  12.              >>test.xls call echo %%.!t!%%
  13.              call set/a num+=%%_!t!%%!var2!
  14.              )
  15.        call set num=%%num:~,-!n!%%.%%num:~-!n!%%
  16.        >>test.xls echo %%a:%%b        !num!
  17.     for %%i in (n m var1 num mn t) do set %%i=
  18.   ) else (
  19.     for /f "tokens=1* delims=." %%i in ("%%c") do (
  20.        set /a m+=1
  21.          set "_!m!=%%i"
  22.            set ".!m!=%%b                %%c"
  23.            if not "%%j"=="" (
  24.            set var1=!var1! %%j
  25.            for /f "delims=:" %%l in ('^(echo %%j^&echo.^)^|findstr /o ".*"') do set/a s=%%l-3
  26.            if !s! gtr !n! set/a n=s
  27.          ) else set var1=!var1! 0
  28.        )
  29.      )
  30.    )
  31. )
复制代码

作者: batman    时间: 2008-12-16 17:20

原帖由 terse 于 2008-12-15 23:17 发表
学习了 先计算位数  这样小数可以不考虑其位数
@echo off&setlocal enabledelayedexpansion
for /f "tokens=1-3 delims=        " %%a in ('type test.xls') do (
  if not defined flag (
    echo %%b         ...

trese兄是不是写得复杂了点。。。。
作者: terse    时间: 2008-12-16 17:36

原帖由 batman 于 2008-12-16 17:20 发表

trese兄是不是写得复杂了点。。。。

确实如兄所言  
计算位数 且分步了 然后补位  
效率都给了计算位数  不考虑位数代码效率似乎可提高些许
发个 小数点后5位的
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1-3 delims=    " %%a in ('type "test.xls"') do (
  3.   if not defined flag (
  4.      echo %%b        %%c>test.xls&set "flag=a"
  5.      ) else (
  6.        if "%%c"=="" (
  7.        >>test.xls echo %%a:%%b    !num:~,-5!.!num:~-5!
  8.        set num=
  9.      ) else (
  10.        >>test.xls echo %%b        %%c
  11.        set str=%%c
  12.        set str1=!str:*.=!
  13.        if "!str1!"=="%%c" set str1=
  14.        call set str2=%%str:.!str1!=%%
  15.        set str1=!str1!00000
  16.        set str1=!str1:~,5!
  17.        set/a num+=!str2!!str1!
  18.      )
  19.    )
  20. )
  21. pause
复制代码

[ 本帖最后由 terse 于 2008-12-16 22:23 编辑 ]
作者: qlcom    时间: 2008-12-18 20:01

  1. @echo on &setlocal enabledelayedexpansion
  2. set/a m=2,n=-1
  3. for /f "tokens=1-3 delims=        " %%i in (test.xls) do (
  4.         set/a n+=1
  5.         if !n!==0 (>test.xls echo %%j        %%k) else (
  6.                 if "%%j"=="total" (
  7.                 >>test.xls echo %%i:%%j        =sum(b!m!:b!n!^)
  8.                 set/a m=n+2
  9.                 ) else (
  10.                 >>test.xls echo %%j        %%k
  11.                 )
  12.         )
  13. )
  14. exit
复制代码
echo以及delims后面的空格都是一个TAB字符.顺便问问各位老大,怎么用p把数据写进已经排版的xls文件(比如居中,改变了列宽等)中呢?

[ 本帖最后由 qlcom 于 2008-12-18 20:15 编辑 ]
作者: batman    时间: 2008-12-19 08:19

原帖由 qlcom 于 2008-12-18 20:01 发表
@echo on &setlocal enabledelayedexpansion
set/a m=2,n=-1
for /f "tokens=1-3 delims=        " %%i in (test.xls) do (
        set/a n+=1
        if !n!==0 (>test.xls echo %%j        %%k) else (
    ...

set/a m=n+2 兄弟可以仔细看下文件是没有规律的,但你这种方法确是可取的,利用xls的函数公式,好!为这思路加分。
作者: qlcom    时间: 2008-12-19 12:23

原帖由 batman 于 2008-12-19 08:19 发表

set/a m=n+2 兄弟可以仔细看下文件是没有规律的,但你这种方法确是可取的,利用xls的函数公式,好!为这思路加分。


谁说没规律,total占一行(而去掉第一行后,除了total所在的行以外都要参加计算),下一个计算起点比起上一个计算终点的行数刚好相差2,顺便麻烦楼主帮我在本版求问的帖子解下锁,谢谢!
作者: jains521    时间: 2012-10-17 15:47

加减法的运算就按照大数的写法就行了.
小数点后面补0到相等长度.在计算. 判断是否有进位.之后在处理整数..整数我想个人的工资不会有超过8位数的人才吧.
所以整体思路. 区分整数和小数,,小数补0至2数相等长度.在按大数四则计算小数.
作者: jains521    时间: 2012-11-19 20:11

  1. @echo off & setlocal enabledelayedexpansion
  2. cd.>_new.xls
  3. ::解题思路为提升小数为整数
  4. for /f "tokens=1,2,3 delims= " %%i in (test.xls) do (
  5. if "%%j" equ "total" (
  6. echo %%i %%j !_%%i:~0,-2!.!_%%i:~-2!>>_new.xls
  7. ) else (
  8. echo %%i %%j %%k>>_new.xls
  9. set _tmp=%%k
  10. set /a _decimal=!_tmp:.=*0+!
  11. set /a "_%%i+= _decimal + _tmp*100"
  12. )
  13. )
  14. pause
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2