dbTalk Databases Forums  

Drillthrough Excel XP and AS 2000 -- The final sheet you want

microsoft.public.sqlserver.olap microsoft.public.sqlserver.olap


Discuss Drillthrough Excel XP and AS 2000 -- The final sheet you want in the microsoft.public.sqlserver.olap forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Arun
 
Posts: n/a

Default Drillthrough Excel XP and AS 2000 -- The final sheet you want - 03-21-2005 , 03:51 AM






I saw lots of articles for implementing drillthrough. I have taken the
best bits of all and modified them to work for multi partition cube.
This works for most of the times.. Simply add this to bas file.

Option Explicit

Private lasterr As Integer
Private pfcombo() As Integer
Private pfarray() As Integer
Private row As Integer
Private col As Integer
Private pfdim As Integer

Private dduct As Boolean

Private dtStart As Date


Const WAITSTRING As String = "Retreiving detail data..."
Const MAXROWS As Integer = 0
Const TIMEOUT As Integer = 60 * 5 '5 minutes

'App specific constants
Const APPNAME As String = "Reporting"
Const wsName As String = "Drillthough"

Sub Drillthrough()

' History
' Modified by Arun NS : To work with cube having multiple
partitions.
' Also works for cubes that return data with duplicate column name
in recordset.
'
' Page field logic : Simon C.H. Ng @ Mar,28-2003. email:
simonchng (AT) mesiniga (DOT) com.my
' Source :
http://msdn.microsoft.com/library/de...extendolap.asp

Dim conn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As ADODB.Recordset

Dim pcell As PivotCell
Dim pt As PivotTable
Dim pf As PivotField
Dim ws As Worksheet

Dim qry As String
Dim msgstr As String
Dim mbrname As String
Dim drill_qry As String

Dim n As Integer, m As Integer
Dim loopmax As Integer
Dim axisn As Integer
Dim i As Integer

Dim rsinit As Boolean
Dim fldval As Variant

dtStart = Now
On Error GoTo errmsg


Set pcell = ActiveCell.PivotCell

On Error GoTo 0
If Not (pcell.PivotTable.PivotCache.OLAP) Then GoTo errmsg
If pcell.PivotCellType <> xlPivotCellValue Then GoTo errmsg

Set pt = pcell.PivotTable

If Not pt.PivotCache.IsConnected Then pt.PivotCache.MakeConnection

Set conn = pt.PivotCache.ADOConnection
conn.CommandTimeout = 0
Set cmd.ActiveConnection = conn
conn.CommandTimeout = TIMEOUT

'identify how many dimensions in the PageField
pfdim = pt.PageFields.Count
loopmax = 1

'This section only applicable when there are dimensions in the
pagefield area
If pfdim > 0 Then
'create an array to hold the values for (PageField index,
number of selected members, balance counter)
ReDim pfarray(pfdim - 1, 2)

'Find out how members are selected in each pagefield Dimension
lasterr = 0
For n = 0 To (pfdim - 1)
m = 1
Set pf = pt.PageFields(n + 1)
If pf.DataRange = "(Multiple Items)" Then
On Error GoTo pferr
Do While True
mbrname = pf.CurrentPageList(m)
If lasterr = 9 Then
lasterr = 0
Exit Do
End If
m = m + 1
Loop
On Error GoTo 0

pfarray(n, 0) = n + 1
pfarray(n, 1) = m - 1
pfarray(n, 2) = m - 1
Else
If Left(pf.DataRange, 3) = "All" Then
pfarray(n, 0) = n + 1

'Assign a value of 0 here to signify that this
dimension
'is set to the ALL level
pfarray(n, 1) = 0
pfarray(n, 2) = 0
Else
pfarray(n, 0) = n + 1

'All others where only one member is selected
assign a value of one
pfarray(n, 1) = 1
pfarray(n, 2) = 1
End If
End If

Next

'Calculate how many times to loop and store it to loopmax
For n = 0 To (pfdim - 1)
If pfarray(n, 1) <> 0 Then
loopmax = loopmax * pfarray(n, 1)
End If
Next

'Create an array to hold the index combinations of the selected
members in the pagefield
ReDim pfcombo(loopmax - 1, pfdim - 1)
For row = 1 To loopmax
col = 1
MakeCombo col
Next
End If

rsinit = True

'Begin the loop here
For n = 1 To loopmax
axisn = 0
drill_qry = "Drillthrough maxrows " & CStr(MAXROWS) & " Select
"

'Include row coordinates in drillthrough query
For i = 1 To pcell.RowItems.Count - 1
If pcell.RowItems(i).Parent.CubeField.Name <>
pcell.RowItems(i + 1).Parent.CubeField.Name Then
drill_qry = drill_qry & "{" & pcell.RowItems(i) & "} on
" & axisn & ", "
axisn = axisn + 1
End If
Next i
If pcell.RowItems.Count > 0 Then
drill_qry = drill_qry & "{" & pcell.RowItems(i) & "} on " &
axisn & ", "
axisn = axisn + 1
End If

'include column coordinates in drillthrough query
For i = 1 To pcell.ColumnItems.Count - 1
If pcell.ColumnItems(i).Parent.CubeField.Name <>
pcell.ColumnItems(i + 1).Parent.CubeField.Name Then
drill_qry = drill_qry & "{" & pcell.RowItems(i) & "} on
" & axisn & ", "
axisn = axisn + 1
End If
Next i
If pcell.ColumnItems.Count > 0 Then
drill_qry = drill_qry & "{" & pcell.ColumnItems(i) & "} on
" & axisn & ", "
axisn = axisn + 1
End If

'include page fields in drillthrough query
If pfdim > 0 Then
For i = 1 To pfdim
Set pf = pt.PageFields(i)
If pfarray(i - 1, 1) = 1 Then
'This part is used for those dimensions in the
pagefield that has only one memberSelected
On Error Resume Next
drill_qry = drill_qry & "{" &
pt.PageFields(i).CurrentPageName & "} on " & axisn & ", "
If Err.Number = 1004 Then
drill_qry = drill_qry & "{" &
pf.CurrentPageList(pfcombo(n - 1, i - 1)) & "} on " & axisn & ", "
End If
axisn = axisn + 1
Else
'This part is used for thosedimensions in the
pagefield that has more than member Selected
'Note that dimensions placed in the pagefield that
is set at the all level is ignored.
If pfcombo(n - 1, i - 1) > 0 Then
drill_qry = drill_qry & "{" &
pf.CurrentPageList(pfcombo(n - 1, i - 1)) & "} on " & axisn & ", "
axisn = axisn + 1
End If
End If
Next
End If

drill_qry = Left$(drill_qry, Len(drill_qry) - 2)
drill_qry = drill_qry & " From " & "[" &
pt.PivotCache.CommandText & "]"

On Error GoTo errmsg

DoEvents

Set rs = conn.Execute(drill_qry)
' Set rs = New ADODB.Recordset
' rs.Source = drill_qry
' Set rs.ActiveConnection = conn
' rs.Open

If rsinit Then
'add a new worksheet and give appropriate name
Set ws = Worksheets.Add
ws.Name = GetWorkSheetName(wsName)
rsinit = False
End If

If Not RecordSetToExcel(rs, ws) Then GoTo ExitSub

On Error GoTo 0

Next


MsgBox "DrillThrough complete." & vbCrLf & "Time taken (in min) : "
& DateDiff("n", dtStart, Now), vbInformation, APPNAME
Exit Sub

pferr:
lasterr = Err.Number
Resume Next

'Various conditions give generic error message
errmsg:
MsgBox "Error occured when attempting to drillthrough !" & vbCrLf &
vbCrLf & _
"Details : " & vbCrLf & Err.Description & vbCrLf & "Source
: " & Err.Source & vbCrLf & "Number : " & Err.Number & vbCrLf & "Time
taken (in min) : " & DateDiff("n", dtStart, Now), vbCritical, APPNAME

ExitSub:
End Sub


Sub MakeCombo(col)
'************************************************* ************
'* Coded by Simon C.H. Ng @ Mar,28-2003
'* email: simonchng (AT) mesiniga (DOT) com.my
'************************************************* ************

'This subroutine is used to handle dynamic recursive looping
'for an unknown number of dimensions placed which is only
ascertained at runtime

'assign the combo array with the last column in the pfarray
'Note, pfarray(n,2) is used to store the number signifying the
remaining numbers not used in the combo
pfcombo(row - 1, col - 1) = pfarray(col - 1, 2)

'after assigning the value to the combo for the current row, move
on to the next column
col = col + 1
If col <= pfdim Then
'Recurse for the next column
MakeCombo (col)
End If

'rollback to the previous column
col = col - 1

If col > 0 Then
If col = pfdim Then
'If the last column in the combo array, check the value of
the 3rd
'column in pfarray. 3 possible combination of values can
arise here i.e.
'0,1 or more than 1. If it is 0, do nothing but set the
variable dduct to
'true. The variable dduct is used to tell the next col-1 to
reduce the value
'in the 3rd column of pfcombo by 1.
Select Case pfarray(col - 1, 2)
Case 0
dduct = True
Case 1
dduct = True
pfarray(col - 1, 2) = pfarray(col - 1, 1)
Case Else
pfarray(col - 1, 2) = pfarray(col - 1, 2) - 1
dduct = False
End Select
Else
If dduct Then
Select Case pfarray(col - 1, 2)
Case 0
dduct = True
Case 1
dduct = True
pfarray(col - 1, 2) = pfarray(col - 1, 1)
Case Else
pfarray(col - 1, 2) = pfarray(col - 1, 2) - 1
dduct = False
End Select
End If
End If

End If

End Sub

Private Function RecordSetToExcel(rs As Recordset, ws As Worksheet) As
Boolean
Dim recArray As Variant
Dim fldCount As Integer
Dim recCount As Integer

On Error GoTo Err_Handler

Do While Not (rs Is Nothing)
If ws.UsedRange.Rows.Count = 1 And ws.Cells(1, 1) = "" Then
PopulateHeaders rs, ws
If Val(Mid(Application.Version, 1, InStr(1,
Application.Version, ".") - 1)) > 8 Then
ws.Cells(ws.UsedRange.Rows.Count + 1, 1).CopyFromRecordset
rs
Else
recArray = rs.GetRows
recCount = UBound(recArray, 2) + 1
fldCount = rs.Fields.Count
ws.Cells(ws.UsedRange.Rows.Count + 1, 1).Resize(recCount,
fldCount).Value = TransposeDim(recArray)
End If

Set rs = rs.NextRecordset
Loop
RecordSetToExcel = True

Exit Function
Err_Handler:

MsgBox "Error occured when attempting to drillthrough !" & vbCrLf &
vbCrLf & _
"Details : " & vbCrLf & Err.Description & vbCrLf & "Source
: " & Err.Source & vbCrLf & "Number : " & Err.Number & vbCrLf & "Time
taken (in min) : " & DateDiff("n", dtStart, Now), vbCritical, APPNAME

RecordSetToExcel = False
End Function

Private Function TransposeDim(v As Variant) As Variant
' Custom Function to Transpose a 0-based array (v)

Dim X As Long, Y As Long, Xupper As Long, Yupper As Long
Dim tempArray As Variant

Xupper = UBound(v, 2)
Yupper = UBound(v, 1)

ReDim tempArray(Xupper, Yupper)
For X = 0 To Xupper
For Y = 0 To Yupper
tempArray(X, Y) = Format$(v(Y, X))
Next Y
Next X

TransposeDim = tempArray

End Function

Private Sub PopulateHeaders(rs As Recordset, ws As Worksheet)
Dim fld As ADODB.Field
Dim iCol As Integer

iCol = 1
For Each fld In rs.Fields
ws.Cells(1, iCol) = fld.Name
iCol = iCol + 1
Next

End Sub

Private Function GetWorkSheetName(ParentName As String) As String
Dim wst As Worksheet
Dim cnt As Integer
Dim wsName As String
Dim bSearch As Boolean

cnt = 0

bSearch = True
Do While bSearch
cnt = cnt + 1
wsName = ParentName & "_" & cnt

For Each wst In Worksheets
If wst.Name = wsName Then
bSearch = True
Exit For
End If
bSearch = False
Next
Loop

GetWorkSheetName = wsName

End Function


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.