|
本帖最后由 hfwufanhf2006 于 2020-5-19 13:56 编辑
你测试下这个附件看看,我感觉大面上差不多,细节可能还需要推敲,因为你模拟的数据没有使用价值,看不出具体的效果来;
你原来的代码我全部删掉了,仅在change和selectchange中重写了代码;
有个模块1,是数据有效性的录制宏,我是想抄一下有效性的设置。录制宏得到的代码很长,不影响使用的参数都被删了,只保留了两个参数;
主要思路:
1、可以从 b 列开始一步步往下走,也可以直接进入到 b-f 列的任何一个单元格直接进行编辑(实际意义可能不大);
如果是从b列开始,将会有每一步的具体检查,这个检查动作在 change 里:
s1 = ""
For i = 2 To Target.Column
s1 = s1 & Cells(Target.Row, i)
Next i
这段代码是读出从b列开始到当前列的所有单元格的信息,并连成字符串;
在后面读取源数据时:
s4 = ""
For k = 1 To Target.Column - 1
s4 = s4 & Worksheets("下拉菜单源").Cells(i, k)
Next k
这段代码的结构与上面类似,它读出源数据的信息,这个信息要与上面的信息一致才会被采用,所以:
If Not zd.exists(s) Then '字典的作用只是排除重复值
If s4 = s1 Then '比较,相同的才会被写入变量 s2,s2后面会写入有效性
zd(s) = i
s2 = IIf(Len(s2) = 0, s3 & ",", s2 & s3 & ",")
End If
End If
2、如果是中途任选一个单元格,则是由 selectchange 负责检查,很显然这时不能触发 change,检查的过程略有不同:
If Len(s1) = 0 Then 's1与上面的含义相同,也是 b-f 列的字符串集合
If Not zd.exists(s3) Then
zd(s3) = i
s2 = IIf(Len(s2) = 0, s3 & ",", s2 & s3 & ",")
End If
Else
If s4 = s1 Then
If Not zd.exists(s3) Then
zd(s3) = i
s2 = IIf(Len(s2) = 0, s3 & ",", s2 & s3 & ",")
End If
End If
End If
这里主要的不同,就是当 b-c 列没有实际输入数据时,直接在 d 列编辑是能出现有效性列表的,所以对 if len(s1)=0 做了专门的处理。我不知道这个有没有用?我的想法是:先录入后面,在回到前面去录入也是可以的;
3、虽然你标注了编辑区是 b6:f25,但整个代码只有一个地方是明确标注了这个区域的,其他的地方仅仅只是限制编辑区是 b-f 列,至于行,代码允许任意行。我觉得你这只是个测试代码,也就没那么认真,留给你自己根据实际来调整;
|
|