Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSRS distinct lookupset function

I'm using Join(Lookupset) to find unique group values which returns a sequence number. This is my function:

Join(LookupSet(Fields!itemId.Value & Fields!UseByDate.Value & Fields!rackId.Value
    , Fields!itemId.Value & Fields!UseByDate.Value & Fields!rackId.Value
    , Fields!CustomerSeqNo.Value
    , "PickingList"), ",")

The problem is on some items there are multiple transactions. I want to remove the duplicates.

I found a blog http://blogs.msdn.com/b/bobmeyers/archive/2012/06/18/creating-short-lists-using-the-lookupset-function.aspx but could not get SSRS Report Builder to reference Linq assembly. My issue is

enter image description here

How can I just show the unique values?

like image 791
jhowe Avatar asked Nov 20 '14 19:11

jhowe


3 Answers

You don't need Linq, but you do still need custom code (in BIDS go to Report -> Report Properties -> Code)

You can put a RemoveDuplicates function in here, something like this:

Public Shared Function RemoveDuplicates(m_Array As Object()) As String()

    System.Array.Sort(m_Array)
    Dim k As Integer = 0
    For i As Integer = 0 To m_Array.Length - 1
        If i > 0 AndAlso m_Array(i).Equals(m_Array(i - 1)) Then
            Continue For
        End If
        m_Array(k) = m_Array(i)
        k += 1
    Next

    Dim unique As [String]() = New [String](k - 1) {}

    System.Array.Copy(m_Array, 0, unique, 0, k)

    Return unique

End Function

To use it in your Join:

Join(Code.RemoveDuplicates(LookupSet(...)),",")
like image 87
Paul The Muzz Avatar answered Nov 13 '22 07:11

Paul The Muzz


I agree with @user3697615 that Report Code is best. However, I prefer to build it straight into a string:

public shared function JoinDistinct(
  dups as object(),
  delimiter as string
) as string

  dim result as string = ""
  system.array.sort(dups)

  for i as integer = 0 to dups.length - 1
    if i <> 0 then result += delimiter
    if i = 0 orElse dups(i) <> dups(i-1) then result += dups(i)
  next i

  return result

end function

This way, we eliminate one nested function on the call:

=Code.JoinDistinct(LookupSet(...), ",")
like image 2
pwilcox Avatar answered Nov 13 '22 09:11

pwilcox


If you're like me, you also want the elements in order based on frequency (descending order).

I created the following VisualBasic code to do so

Public Shared Function RemoveDuplicates(dataset As Object()) As String()
    Dim unique As New System.Collections.Generic.List(Of String)
    Dim frequency As New System.Collections.Generic.List(Of Integer)
    For i As Integer = 0 To dataset.Length - 1
        Dim index As Integer = -1
        For j As Integer = 0 To unique.Count - 1
            If dataset(i).Equals(unique(j)) Then
                index = j
                Exit For
            End If
        Next
        If index < 0 Then
          unique.Add(dataset(i))
          frequency.Add(1)
        Else
            frequency(index) += 1
        End If
    Next
    Dim uniqueArray As [String]() = unique.ToArray()
    Array.Sort(frequency.ToArray(), uniqueArray)
    Array.Reverse(uniqueArray)
    return uniqueArray
End Function

This is based off others' answers where the SSRS expression is the following

Join(Code.RemoveDuplicates(LookupSet(...)),",")

Note: I learned VisualBasic in about an hour to solve this problem, so my algorithm probably isn't the most efficient.

like image 1
nothotscott Avatar answered Nov 13 '22 09:11

nothotscott