Hi,
Ik heb een MS Excel werkboek met verschillende tabs. Elke tab bevat query resultaten die vanuit SAP BW gevuld worden. Op deze BW queries zitten standaard Excel grafieken.
Voor mijn klant heb ik een VBA macro geschreven die alle tabs afgaat en de grafieken copy-paste naar een Powerpoint presentatie. Dit werkt al een aantal jaren uitstekend, maar ik heb gemerkt dat user die onder Citrix werken grote problemen ondervinden.
Sommige grafieken komen niet over, andere bevatten oude resultaten etc. Ik ben er voor 98% van overtuigd dat dit komt door clipboard problemen, dus dat het kopieren van een chart (als image!) nog bezig is als hij hem al probeert te pasten in de PPT.
Ik heb al het een en ander geprobeerd, zoals ik met onderstaande snippets probeer te verduidelijken, en het werkt al een stuk beter dan eerst, maar wie kan mij helpen dit hoofdpijndossier te sluiten??
Korte uitleg verwerking
generateSlide1
De functies IsRemoteSession en ClearClipboard heb ik met wat googlen op Citrix fora en zo als volgt gedefinieerd:
IsRemoteSession
ClearClipboard
Ik heb een MS Excel werkboek met verschillende tabs. Elke tab bevat query resultaten die vanuit SAP BW gevuld worden. Op deze BW queries zitten standaard Excel grafieken.
Voor mijn klant heb ik een VBA macro geschreven die alle tabs afgaat en de grafieken copy-paste naar een Powerpoint presentatie. Dit werkt al een aantal jaren uitstekend, maar ik heb gemerkt dat user die onder Citrix werken grote problemen ondervinden.
Sommige grafieken komen niet over, andere bevatten oude resultaten etc. Ik ben er voor 98% van overtuigd dat dit komt door clipboard problemen, dus dat het kopieren van een chart (als image!) nog bezig is als hij hem al probeert te pasten in de PPT.
Ik heb al het een en ander geprobeerd, zoals ik met onderstaande snippets probeer te verduidelijken, en het werkt al een stuk beter dan eerst, maar wie kan mij helpen dit hoofdpijndossier te sluiten??
Korte uitleg verwerking
- Ik roep eerst de functie IsRemoteSession aan. Deze geeft een True indien je onder Citrix werkt. In dat geval zet ik ScreenUpdating op True (normaal kan deze op False staan)
- Ik loop over de slides in mijn PPT. Per slide zoek ik de juiste chart op in de Excel en die copy-paste ik dan als image.
- Voor en na de copy paste doe ik een expliciete ClearClipboard() aanroep, dit om te zorgen dat een vorige grafiek niet nogmaals gepaste kan worden.
- Na elke copy/paste stap doe ik een expliciete DoEvents() om het clipboard tijd te geven te synchroniseren
- Tenslotte nog wat move en resize operaties om de chart op de juiste plek te zetten.
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| ' When running under Citrix, sync issues occur when copy-pasting the charts ' and it can be solved by leaving screenupdating switched on If IsRemoteSession() = True Then Application.ScreenUpdating = True Else Application.ScreenUpdating = False End If ' Loop over slides in PPT template For Each pptSlide In pptPres.Slides Select Case pptSlide.Name Case "Slide1" ' Title page Call generateSlide1(pptSlide, projectID) ' (...) Many more End Select Next |
generateSlide1
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| Private Sub generateSlide1(pptSlide As Object) Dim objName As String Dim updScreen As Boolean Dim shShape As Object Dim rng As Range, item As Range On Error Resume Next ' Copy the Gantt chart ' -------------------- ActiveWorkbook.Sheets("Schedule (G)").Activate If Range("rngSchedule").Rows.Count > 1 Then 'Preserve ScreenUpdating status updScreen = Application.ScreenUpdating Application.ScreenUpdating = True 'Otherwise CopyPicture of cell data does not work Call ClearClipboard ActiveSheet.Range("rngGanttChart").Select Selection.CopyPicture Appearance:=xlScreen, Format:=xlBitmap ' Copy the range as xlBitmap, not xlPicture ' to prevent clipping when Gantt is large DoEvents ' Make sure clipboard can be synchronized objName = pptSlide.Shapes.Paste.Name DoEvents ' Make sure clipboard can be synchronized 'Reset screenupdating to what it was Application.ScreenUpdating = updScreen pptSlide.Shapes(objName).LockAspectRatio = msoTrue pptSlide.Shapes(objName).Left = 2.5 pptSlide.Shapes(objName).Top = 28 ' Make sure the item fits in the bounding box pptSlide.Shapes(objName).Width = 720 If pptSlide.Shapes(objName).Height > 62 Then pptSlide.Shapes(objName).Height = 62 End If ' Clear the text box. In case the Gantt chart is smaller than whole width, ' part of this text becomes visible pptSlide.Shapes("Text Box 47").TextFrame.TextRange.Text = "" Else ' In case no Gantt could be generated pptSlide.Shapes("Text Box 47").TextFrame.TextRange.Text = msNODATAFOUNDREWORK End If ' (....) etc etc |
De functies IsRemoteSession en ClearClipboard heb ik met wat googlen op Citrix fora en zo als volgt gedefinieerd:
IsRemoteSession
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| Public Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long Public Const c_SM_REMOTESESSION As Long = 4096, _ c_SM_REMOTECONTROL As Long = 8193 Public Function IsRemoteSession() As Boolean Dim lSession As Long ' Test if running under WTS lSession = GetSystemMetrics(c_SM_REMOTESESSION) If lSession <> 0 Then IsRemoteSession = True Else IsRemoteSession = False End If End Function |
ClearClipboard
Visual Basic:
1
2
3
4
5
6
7
8
9
| Public Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Public Declare Function EmptyClipboard Lib "user32" () As Long Public Declare Function CloseClipboard Lib "user32" () As Long Public Sub ClearClipboard() OpenClipboard (0&) EmptyClipboard CloseClipboard End Sub |
[ Voor 0% gewijzigd door curkey op 21-04-2010 12:28 . Reden: Syntax highlighting on :-) ]