2016-08-17 2 views
1

다음과 같은 데이터 집합의 경우 행 1의 값이 지정된 값과 같으면 모든 ID 열을 반환합니다. 특정 열에있는 셀의 값이 3 미만이다 행의 값 (단, 값은 ID 열 또는 1 행 "헤더"의 반복하지 않는다.)UDF : 열의 x보다 작은 셀 값의 경우 첫 번째 열의 모든 값을 반환하십시오.

ID | X | Y | Z  
123 | 1 | 2 | 5  
456 | 2 | 6 | 4  
789 | 6 | 1 | 2 

예컨대, 만일 열의 헤더 = "X" , "123, 456"의 반환 값. Y이면 "123, 789". Z이면 "789". 내 요구 사항을 해결하기 위해 가까운 "multicat formula" (링크 된 답변 편집에 있음)의 변형을 발견했지만 문제를 적응하는 데 어려움이 있습니다.

예를 들어 X에서와 같은 함수를 실행하면 "1, 2"값이 반환됩니다. 결과는 평가되는 열에 관계없이 ID 열에서 항상 가져와야합니다. 그 부분은 단순해야하지만 평가 된 열이 가변적 일 수 있기 때문에 오프셋을 사용하지 않고 수행하는 방법을 이해할 수는 없습니다.

필자는 "a1 : d1 = X의 셀 값이면 MultiCat a1 : a4 [선택한 열]의 셀 값이 <입니다."라는 간단한 영어 논리가 필요합니다. " Match 함수를 사용하여 평가를 수행하려는 열을 찾을 수 있으며 결과를 단일 셀에 연결해야한다고 생각하는 코드가 있습니다.

필자는 Match 결과를 함수에 통합하는 방법이나 ID 열을 연결하는 함수를 얻는 방법을 이해할 수 없습니다.

답변

0

다음과 같이 할 수 있습니다. a) 함수에 ID 열을 하드 코딩 할 수 있습니다. b) 매개 변수를 추가하여 ID 열을 함수에 전달합니다. c) 열 머리글 이름을 함수에 전달합니다. 샘플 이미지의 G2에서

Option Explicit 

Public Function MultiCat2A(ByRef rRng As Excel.Range, _ 
          Optional ByVal sDelim As String = ",") _ 
         As String 
    Dim c As Long, cRng As Range 

    'restrict rRng to the .UsedRange 
    Set rRng = Intersect(rRng, rRng.Parent.UsedRange) 
    'set cRng to another column but equal to rRng 
    Set cRng = Intersect(rRng.EntireRow, rRng.Parent.Columns("A")) 

    For c = 1 To rRng.Count 
     If rRng(c).Value < 3 Then 
     MultiCat2A = MultiCat2A & sDelim & cRng(c).Text 
     End If 
    Next c 

    MultiCat2A = Mid(MultiCat2A, Len(sDelim) + 1) 
    If CBool(Len(sDelim)) Then 
     Do While Right(MultiCat2A, Len(sDelim)) = sDelim 
      MultiCat2A = Left(MultiCat2A, Len(MultiCat2A) - Len(sDelim)) 
     Loop 
    End If 
End Function 

Public Function MultiCat2B(ByRef cRng As Range, _ 
          ByRef rRng As Excel.Range, _ 
          Optional ByVal sDelim As String = ",") _ 
         As String 
    Dim c As Long 

    'restrict rRng to the .UsedRange 
    Set rRng = Intersect(rRng, rRng.Parent.UsedRange) 
    'resize cRng to the same as rRng 
    Set cRng = cRng(1, 1).Resize(rRng.Rows.Count, rRng.Columns.Count) 

    For c = 1 To rRng.Count 
     If rRng(c).Value < 3 Then 
     MultiCat2B = MultiCat2B & sDelim & cRng(c).Text 
     End If 
    Next c 

    MultiCat2B = Mid(MultiCat2B, Len(sDelim) + 1) 
    If CBool(Len(sDelim)) Then 
     Do While Right(MultiCat2B, Len(sDelim)) = sDelim 
      MultiCat2B = Left(MultiCat2B, Len(MultiCat2B) - Len(sDelim)) 
     Loop 
    End If 
End Function 

Public Function MultiCat2C(ByVal sHdr As String, _ 
          ByRef rRng As Excel.Range, _ 
          Optional ByVal sDelim As String = ",") _ 
         As String 
    Dim c As Long, cRng As Range 

    'restrict rRng to the .UsedRange 
    Set rRng = Intersect(rRng, rRng.Parent.UsedRange) 
    'find the column by header label 
    c = Application.Match(sHdr, rRng.Parent.Rows(1), 0) 
    'offset cRng by its column vs rRng's column 
    Set cRng = rRng(1, 1).Offset(0, c - rRng.Column) 

    For c = 1 To rRng.Count 
     If rRng(c).Value < 3 Then 
     MultiCat2C = MultiCat2C & sDelim & cRng(c).Text 
     End If 
    Next c 

    MultiCat2C = Mid(MultiCat2C, Len(sDelim) + 1) 
    If CBool(Len(sDelim)) Then 
     Do While Right(MultiCat2C, Len(sDelim)) = sDelim 
      MultiCat2C = Left(MultiCat2C, Len(MultiCat2C) - Len(sDelim)) 
     Loop 
    End If 
End Function 

: 같은 G5,

=MultiCat2A(B2:B4) 
=MultiCat2B($A2:$A4, B2:B4) 
=MultiCat2C("ID", B2:B4) 
=MultiCat2C($A1, B2:B99) 

채우기 바로 필요.

concat_again

+0

가 BTW, 내가 UDF 함수로 전달 된 모든 매개 변수를 '믿고 ByVal' 관계없이 같은 선언 할 무엇; 나는 이것을 확인하기 위해 약간의 google-fu를해야 할 것이다. – Jeeped

관련 문제