ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 不规则结构

[讨论] 监考问题的一种实现方式

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-6-13 10:26 来自手机 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
不规则结构 发表于 2024-6-13 09:58
同一人不得监考多个考场?这一点没有想到。再设一个一点记录考场,取随机数判断一下,不知道是否可行?晚 ...

同列不能冲突,还需要一个字典

TA的精华主题

TA的得分主题

发表于 2024-6-13 10:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
哈哈,看你代码笑喷

TA的精华主题

TA的得分主题

发表于 2024-6-13 11:05 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
wang-way 发表于 2024-6-13 09:28
私我 我私你参考一下

感谢老师给我机会,我现在的能力可能悟不出这里的逻辑。
等我学的差不多了,再来讨教一二。谢谢了

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-6-13 20:39 | 显示全部楼层
wang-way 发表于 2024-6-13 09:27
你私我 我私你学习

设一个字典  把教师名作为key,因为考场通常9个以内,所有考过的考场作为item 不停&。判断要加instr就可以了 。是这样搞吧

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-6-13 20:43 | 显示全部楼层
wang-way 发表于 2024-6-13 09:25
模拟数据不合适,业务还要考虑同一列不能冲突

早上起来写的,还有一个bug.同一行用的是监考2次作为终止条件,但如果之前监考了3次,那就共5次了。

TA的精华主题

TA的得分主题

发表于 2024-6-13 21:50 来自手机 | 显示全部楼层
ytmpgght 发表于 2024-6-13 11:05
感谢老师给我机会,我现在的能力可能悟不出这里的逻辑。
等我学的差不多了,再来讨教一二。谢谢了

请移步  https://mp.weixin.qq.com/s?__biz=MzIyNzI3OTIyNQ==&mid=2650212710&idx=1&sn=4bffd31c97f43eb948e4616640dcab44&chksm=f0600170c7178866a3c5a2e1ee66cc0b18dc893a13ad05cae80f9c0ed861c8820656ce95ecc7#rd

TA的精华主题

TA的得分主题

发表于 2024-6-13 22:14 | 显示全部楼层
  1. Public Sub X2()
  2.     ' 定义变量
  3.     Dim proc_own, proc_count, teacher_proc_times, room_proc_times, proc_rnd
  4.     ' 代码从这里开始写
  5.     ' 声明变量eRow,eCol存储末行行号和末列列号
  6.     Dim eRow As Long, eCol As Long
  7.     ' 声明工作簿变量wb和工作表变量sht
  8.     Dim wb As Workbook, sht As Worksheet
  9.     ' 设置wb为当前工作簿
  10.     Set wb = Application.ThisWorkbook
  11.     ' 声明工作表对象变量pSht
  12.     Dim pSht As Worksheet
  13.     ' 设置sht为指定名称的工作表,引号内填写工作表名称
  14.     Set sht = wb.Worksheets(1)
  15.     ' 设置psht为工作表,在引号内填写工作表名称
  16.     Set pSht = wb.Worksheets(2)
  17.     ' 声明名为d的变量
  18.     Dim dTeacherOfClass As Object
  19.     Dim dRoom, dTeacher, dSubject
  20.     ' 创建字典用来保存验证条件
  21.     Set dTeacher = CreateObject("Scripting.Dictionary")
  22.     Set dSubject = CreateObject("Scripting.Dictionary")
  23.     Set dRoom = CreateObject("Scripting.Dictionary")
  24.     ' 创建一个字典d
  25.     Set dTeacherOfClass = CreateObject("Scripting.Dictionary")
  26.     ' 使用With语句,方便对工作表Sht进行多次操作
  27.     With sht
  28.         '读取参数
  29.         If .Range("j2").Value = "任教班级" Then
  30.             proc_own = True
  31.         Else
  32.             proc_own = False
  33.         End If
  34.         teacher_proc_times = .Range("j3").Value
  35.         room_proc_times = .Range("j4").Value
  36.         proc_count = .Range("j5").Value
  37.         If .Range("j6").Value = "是" Then
  38.             proc_rnd = True
  39.         Else
  40.             proc_rnd = False
  41.         End If
  42.         ' 设置范围为从A2开始的当前区域
  43.         Set Rng = .Range("A2").CurrentRegion
  44.         ' 将范围Rng的值赋给数组Arr
  45.         arr = Rng.Value
  46.         ' 变量 i 从数组Arr第一维 最小索引开始,遍历至最大索引
  47.         ' 变量 j 从数组Arr第二维 最小索引开始,遍历至最大索引
  48.         For i = 2 To UBound(arr)
  49.             For j = 2 To UBound(arr, 2)
  50.                 Key = arr(i, 1)
  51.                 '按班级分工串接教师姓名
  52.                 dTeacherOfClass(Key) = dTeacherOfClass(Key) & "-" & arr(i, j) '串接教师姓名
  53.                 '初始化教师个人已安排监考次数为0
  54.                 dTeacher(arr(i, j)) = 0
  55.             Next j
  56.         Next i
  57.     End With
  58.     With pSht
  59.         ' 获取列A中最大数据行的行号
  60.         eRow = .Cells(.Rows.Count, 1).End(xlUp).Row
  61.         ' 获取第1行中最右侧数据列的列号
  62.         eCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
  63.         .UsedRange.Offset(1, 1).ClearContents
  64.         '循环每一个考场地点
  65.         For i = 2 To eRow Step 1
  66.             '读取考场地点
  67.             cls = .Cells(i, 1).Value
  68.             '任教班级监考  把任教班级的教师放入数组ar
  69.             If proc_own Then
  70.                 ar = Split(Mid(dTeacherOfClass(cls), 2), "-")
  71.             Else
  72.                 '不限制  所有教师放入数组ar
  73.                 's = ""
  74.                 'For Each k In dTeacherOfClass
  75.                  '  s = s & dTeacherOfClass(k)
  76.                 'Next
  77.                 'ar = Split(Mid(s, 2), "-")
  78.                 ar = dTeacher.keys
  79.             End If
  80.             
  81.             
  82.             '循环每个监考科目
  83.             For j = 2 To eCol
  84.                 '读取科目名称
  85.                 sbj = .Cells(1, j).Value
  86.                 '是否打乱顺序
  87.                 If proc_rnd Then
  88.                     br = RndArr(ar)
  89.                 Else
  90.                     br = ar
  91.                 End If
  92.                 '开始挑选老师 初始化名单s为空
  93.                 s = ""
  94.                 For n = 1 To proc_count '几人监考
  95.                     '遍历名单中的每个教师姓名
  96.                     For Each t In br
  97.                         '串接考场与教师姓名,初始化该考场某教师的监考次数
  98.                         If dRoom.exists(cls & t) = False Then dRoom(cls & t) = 0
  99.                         '筛选条件  统一考点不超过次数,                  同一科目不同考场同一教师不能同时监考 ,教师个人监考次数上限不超过次数
  100.                         If dRoom(cls & t) < room_proc_times And dSubject.exists(sbj & t) = False And dTeacher(t) <= teacher_proc_times Then
  101.                             '构建名单
  102.                             s = IIf(s = "", t, s & "-" & t)
  103.                             '更新检验条件
  104.                             dRoom(cls & t) = dRoom(cls & t) + 1 '该考场 某老师监考次数+1
  105.                             dSubject(sbj & t) = 1 '该科目 某教师监考次数为1
  106.                             dTeacher(t) = dTeacher(t) + 1 '教师个人监考次数+1
  107.                             Exit For '退出循环
  108.                         End If
  109.                     Next t
  110.                 Next n
  111.                 '输出名单
  112.                 .Cells(i, j).Value = s
  113.             Next j
  114.         Next i
  115.     End With
  116. End Sub
  117. ' 打乱数组元素 把教师姓名顺序打乱
  118. Function RndArr(ByVal ar)
  119.         ' 循环每一个元素
  120.         For i = 1 To UBound(ar)
  121.             ' 随机产生一个索引范围内的数字
  122.             y = Int(Rnd * (UBound(ar)) + 1)
  123.             ' 交换当前元素和随机下标的元素
  124.             tmp = ar(y)
  125.             ar(y) = ar(i)
  126.             ar(i) = tmp
  127.         Next i
  128.         ' 传回数组
  129.         RndArr = ar
  130. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-6-14 09:23 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-6-14 10:00 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
干扰代码没有必要吧,别把自己带偏了。他原意做白嫖党,你就让他做呗,有什么关系。你的技术长进了,他还在原地踏步。

TA的精华主题

TA的得分主题

发表于 2024-6-14 11:11 | 显示全部楼层
leeson7502 发表于 2024-6-14 10:00
干扰代码没有必要吧,别把自己带偏了。他原意做白嫖党,你就让他做呗,有什么关系。你的技术长进了,他还在 ...

17楼的代码没做成附件我还是不会用
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-6-18 19:43 , Processed in 0.044213 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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