如何使用数据验证将选择限制为列中包含所有唯一条目的列表以及另外一个?

时间:2017-11-07 13:52:26

标签: excel excel-formula

我想要执行以下操作:我有一个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

我想过用宏做这个,但我不想每次改变时都更新它。有人可以帮忙吗?

enter image description here

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) }

这是输出:

Dynamic Data Validation