我想要执行以下操作:我有一个table = Listobject,它有一个名为MasterID的列。有些列具有相同的MasterID,有些列甚至是非。我需要手动添加缺少的MasterID。
我想在MasterID为空的情况下取一行,然后我想点击MasterID列并为该列选择一个ID。它可以是现有ID。哪个是在孔列表列中使用的MasterID的唯一lsit,或者它可以是新的MasterID。如果选择了新ID,它应该是最大MasterID的下一个整数。因此,如果到目前为止最高的masterID是1000,那么新的masterID应该是1001.
所以我想知道是否有办法使用数据验证来建议我下一个更大的MasterID或所有现有的。由于已经填充的MasterID是随机分布的,我需要将其转换为单个公式。
让我们稍微详细说明一下:
如果单元格不是空的,它可以是它想要的任何东西,ELSE单元格需要是listcolumn中使用的值之一或Listcolumn +1的MAXIMUM。
如果可能,我想使用下拉列表。
我用数据验证列表选项尝试了这个,但我无法弄清楚如何。我知道需要有这样的结构:
If Isempty then BeWhatever
Else Be DynamicAdjustedListofEntries OR MaximumEntry+1
我想过用宏做这个,但我不想每次改变时都更新它。有人可以帮忙吗?
答案 0 :(得分:1)
我不认为使用纯Excel可以动态填写列表类型的验证。这是我使用VBA的解决方案。将此宏放在适当的工作表中:
Table26[MasterIDs]
注意:根据您的数据更改Sub Dynamic_Data_Validation(table_range As String)
Dim ids() As Variant 'Didn't declare as Long because JOIN function doesn't accept it
Dim row_count As Long
Dim src As Range, tmp_rng As Range
Dim validation_list As String
Application.ScreenUpdating = False
Set src = Range(table_range)
ids = src.Value
'Change X to some other column name if you don't prefer this
Set tmp_rng = Range("X1").Resize(UBound(ids))
tmp_rng = ids
'If sorted in descending order, it becomes difficult to add the
'(MAX + 1) ID in the beginning of the array
tmp_rng.Sort Key1:=tmp_rng, Order1:=xlAscending
tmp_rng.RemoveDuplicates Columns:=1
row_count = tmp_rng.End(xlDown).Row
'Add the (MAX + 1) ID to the end of the range and resize it
tmp_rng.Cells(row_count + 1).Value = tmp_rng.Cells(row_count).Value + 1
Set tmp_rng = tmp_rng.Resize(row_count + 1)
tmp_rng.Sort Key1:=tmp_rng, Order1:=xlDescending
ids = Application.Transpose(tmp_rng)
tmp_rng.Delete Shift:=xlToLeft
'Perhaps consider adding a code to save the workbook after this line,
'as pressing CTRL + END will move the cursor to column X or whatever you choose
validation_list = Join(ids, ",")
'The existing validation needs to be deleted, otherwise it raises error
src.Validation.Delete
src.Validation.Add Type:=xlValidateList, Formula1:=validation_list
End Sub
。
然后将其粘贴到普通模块中。当然,您可以将这些行直接粘贴到Worksheet_Change过程中。
VBA.Join
我已经使用工作表暂时放置数组项以分类和删除重复项,因为这看起来更容易。另一种方法是操作数组本身中的数组元素,然后将其作为参数传递给signif.floor=function(x,n){
if(x==0)(out=0)
if(x%%round(x)==0 & sign(x)==1){out=as.numeric(paste0(el(strsplit(as.character(x),''))[1:n],collapse=''))*10^(nchar(x)-n)}
if(x%%round(x) >0 & sign(x)==1){out=as.numeric(paste0(el(strsplit(as.character(x),''))[1:(n+1)],collapse=''))}
if(x%%round(x)==0 & sign(x)==-1){out=(as.numeric(paste0(el(strsplit(as.character(x),''))[1:(n+1)],collapse=''))-1)*10^(nchar(x)-n-1)}
if(x%%round(x) <0 & sign(x)==-1){out=as.numeric(paste0(el(strsplit(as.character(x),''))[1:(n+2)],collapse=''))-+10^(-n+1)}
return(out)
}
signif.ceiling=function(x,n){
if(x==0)(out=0)
if(x%%round(x)==0 & sign(x)==1){out=(as.numeric(paste0(el(strsplit(as.character(x),''))[1:n],collapse=''))+1)*10^(nchar(x)-n)}
if(x%%round(x) >0 & sign(x)==1){out=as.numeric(paste0(el(strsplit(as.character(x),''))[1:(n+1)],collapse=''))+10^(-n+1)}
if(x%%round(x)==0 & sign(x)==-1){out=(as.numeric(paste0(el(strsplit(as.character(x),''))[1:(n+1)],collapse='')))*10^(nchar(x)-n-1)}
if(x%%round(x) < 0 & sign(x)==-1){out=as.numeric(paste0(el(strsplit(as.character(x),''))[1:(n+2)],collapse=''))}
return(out)
}
。
这是输出: