1234

ExcelHome技术论坛

用户名  找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

帖子
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3028|回复: 8

求助Networdays函数怎样改编下可以增加计算工作日

[复制链接]

TA的精华主题

TA的得分主题

发表于 2012-10-29 16:59 | 显示全部楼层 |阅读模式
Networkdays函数只能自定义减去法定节假日或自定义休息日,但如果公司调整了工作日和休息日,本来系统默认的休息日安排上班了,怎样通过改编函数VBA代码进行实现?求高手提供代码,十分感谢!

该贴已经同步到 冰蓝小培的微博

TA的精华主题

TA的得分主题

发表于 2012-10-30 00:43 | 显示全部楼层
本帖最后由 hehex 于 2012-10-30 00:43 编辑

这个版大都是初学者,估计很难有能力做到楼主的要求。
楼主不妨把这个问题提到vba程序开发版,那里很多高手一定可以编一个完美的自定义函数给你。

我试写了一个很不成熟的自定义函数,楼主可以试用看看。
目前所有参数只支持单元格引用,用具体日期做参数还不能工作正常
格式是:test_days(起始日期(单元格引用),终止日期(单元格引用),特殊假日(单元格引用),工作的假日(单元格引用))
必须写全所有参数,即使没有特殊假日,可以写一个空单元格,但是不可以不写。
具体可以看下附件文件,只是勉强work。


test_days.rar

28.05 KB, 下载次数: 36

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-30 08:41 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
{:soso_e102:}十分感谢

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-30 09:56 | 显示全部楼层
hehex 发表于 2012-10-30 00:43
这个版大都是初学者,估计很难有能力做到楼主的要求。
楼主不妨把这个问题提到vba程序开发版,那里很多高手 ...

有个小小的Bug,输入的norest_days值即使不在开始和结束日期范围内,也会被增加计算到总天数里面。能不能帮忙调整下代码呀,偶只能稍微看得懂,但自己不会写,呜呜。。。拜托

TA的精华主题

TA的得分主题

发表于 2012-10-30 11:19 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
okay, 我去修改下,我也在一直进行完善,当成对自己的一种锻炼。
另外请注意,这程序好像在excel 2003 下运行有问题,起因是2003 vba 好像无法直接调用工作表函数networkdays,我公司这里只有英文的2003环境,我在家里是用excel 2007 写的,这里只能改代码,具体是否工作还得测试了。

TA的精华主题

TA的得分主题

发表于 2012-10-30 11:28 | 显示全部楼层
请参考附件:
  1. Option Explicit

  2. Private Function test_days(s_date As Range, e_date As Range, sp_holidays As Range, norest_days As Range) As Integer
  3. '    Dim start_date, end_date       前面代码是尝试使用时间或者单元格引用,目前使用具体时间不work
  4. '    If IsObject(s_date) Then
  5. '        start_date = s_date.Value
  6. '    Else
  7. '        start_date = s_date
  8. '    End If
  9. '    If IsObject(e_date) Then
  10. '        end_date = e_date.Value
  11. '    Else
  12. '        end_date = e_date
  13. '    End If

  14.     If TypeName(start_date) <> "Date" Or TypeName(end_date) <> "Date" Then Exit Function
  15.     If end_date - start_date < 0 Then Exit Function
  16.     If s_date.Count > 1 Or e_date.Count > 1 Then    '判断起始终止日期单元格
  17.         MsgBox "起始日期和终止日期只能是唯一单元格", 16, "错误"
  18.         Exit Function
  19.     End If

  20.     If TypeName(s_date.Value) <> "Date" Or TypeName(e_date.Value) <> "Date" Then '判断,选择起始和终止时间的单元格是否为日期值,如果不是就退出
  21.         MsgBox "起始时间或者终止时间单元格内容不是日期值", 16, "错误"
  22.         Exit Function
  23.     End If

  24.     If (e_date.Value - s_date.Value) < 0 Then
  25.         MsgBox "目前暂不能支持终止时间在起始时间之前的计算", 16, "错误"
  26.     End If

  27.     Dim rng As Range
  28.         For Each rng In norest_days
  29.             
  30.             If TypeName(rng.Value) <> "Date" Then '判断删减休息日的单元格引用是否是日期值,如果不是退出
  31.                MsgBox "单元格" & rng.Address & "不是日期型数据", 16, "错误"
  32.                Exit Function
  33.             End If
  34.             
  35.             If rng.Value < s_date.Value Or rng.Value > e_date.Value Then
  36.                 MsgBox "单元格" & rng.Address & "日期越界,不在起始终止日期范围内", 16, "错误"
  37.                 Exit Function
  38.             End If
  39.             
  40.             If WorksheetFunction.Weekday(rng.Value, 2) <> 6 And WorksheetFunction.Weekday(rng.Value, 2) <> 7 Then '判断是否为周6,日系统函数确认的休息日,如果不是就退出
  41.                 MsgBox "单元格" & rng.Address & "内容不是系统内假期", 16, "错误"
  42.                 Exit Function
  43.             End If
  44.             
  45.        Next

  46.     If sp_holidays Is Nothing Then
  47.         test_days = WorksheetFunction.networkdays(s_date, e_date)
  48.     Else
  49.         test_days = WorksheetFunction.networkdays(s_date, e_date, sp_holidays)
  50.     End If
  51.     Dim no_rest As Integer
  52.     no_rest = norest_days.Count
  53.     test_days = test_days + no_rest

  54. End Function         
  55.          
复制代码

test_days.zip

15.18 KB, 下载次数: 6

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-30 13:02 | 显示全部楼层
hehex 发表于 2012-10-30 11:28
请参考附件:

我这边是2010版的excel,加进去后运行会报错,可能我输入的Norest_day的值超过开始和结束日期造成的,但实际情况是我会将全年sp_holidays和Norest_day填好,每一个人公式中选中的这两个区域都一样,只是每个人的开始日期和结束日期不同,这样的话,如果Norest_day超过范围,其实不报错,而是不会去count。

TA的精华主题

TA的得分主题

发表于 2012-10-30 13:32 | 显示全部楼层
本帖最后由 hehex 于 2012-10-30 13:33 编辑

已经做了修改,现在越界的日期应该会减去计数,不会报错退出了。
请参看附件,我现在是盲改,没有环境能验证代码的效果。
如果在03 下完成这个任务,系统networkdays的功能要完全用代码重现,这个工作量就有点大了。

具体代码修改在:
将no_rest 计数的定义,赋值提前到 For each in 循环之前
Dim rng As Range, no_rest As Integer
no_rest = norest_days.Count       ' no_rest 赋予初始的所有不休息假日的值,这里是所有暂时不判断

在for each in 循环中判断日期是否越界:
     If rng.Value < s_date.Value Or rng.Value > e_date.Value Then
‘如果不休息的假日早于初始日期或者晚于终止日期
            no_rest = no_rest - 1 ' 将这条记录的计数去掉
        End If
这样一直到循环结束,就将所有的越界日期计数去掉了。算法是这样,但是我这里无法调试,不知道具体实现的结果会不会正确。

详见附件

test_days.zip

15.01 KB, 下载次数: 16

TA的精华主题

TA的得分主题

发表于 2012-10-30 21:48 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 hehex 于 2012-10-30 21:50 编辑

上面的附件有问题,是我在公司用excel 2003 编辑的代码然后保存的,不知道为什么出错了,在07 里也不能执行了。
看来是遇到了传说中的兼容性问题了。
回来重写了需要修改的部分,应该是可以达到楼主要求的去除越界日期计数的效果了。
楼主请试用一下,看看是否可以在工作上应用。

我会自己再完善改写这个自定义函数: 可以实现日期型参数的传递,3,4 参数可以实现空值传递 (optional)并实现日期数组参数的
还需要学习很多东西啊。                     

test_days.rar

18.84 KB, 下载次数: 25

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

1234

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-4-27 20:20 , Processed in 0.024514 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表