-
Notifications
You must be signed in to change notification settings - Fork 5
/
XTemplatePpt.min.bas
278 lines (278 loc) · 10.4 KB
/
XTemplatePpt.min.bas
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
Attribute VB_Name = "XTemplatePpt"
Option Explicit
Private Function GetAllText() As String
Dim individualSlide As Slide
Dim individualShape As Shape
Dim individualSmartArtNode As SmartArtNode
Dim individualRow As Row
Dim individualCell As Cell
Dim individualDesign As Design
Dim individualCustomLayout As CustomLayout
Dim allStrings$
For Each individualSlide In ActivePresentation.Slides
For Each individualShape In individualSlide.Shapes
On Error Resume Next
allStrings = allStrings + individualShape.TextFrame.TextRange.Text
On Error GoTo 0
If individualShape.HasSmartArt Then
For Each individualSmartArtNode In individualShape.SmartArt.AllNodes
allStrings = allStrings + individualSmartArtNode.TextFrame2.TextRange.Text
Next
End If
If individualShape.HasChart Then
If individualShape.Chart.HasTitle Then
allStrings = allStrings + individualShape.Chart.ChartTitle.Text
End If
End If
On Error Resume Next
For Each individualRow In individualShape.Table.Rows
For Each individualCell In individualRow.Cells
allStrings = allStrings + individualCell.Shape.TextFrame.TextRange.Text
Next
Next
On Error GoTo 0
Next
On Error Resume Next
allStrings = allStrings + individualSlide.HeadersFooters.Header.Text
On Error GoTo 0
On Error Resume Next
allStrings = allStrings + individualSlide.HeadersFooters.Footer.Text
On Error GoTo 0
Next
For Each individualDesign In ActivePresentation.Designs
For Each individualShape In individualDesign.SlideMaster.Shapes
On Error Resume Next
allStrings = allStrings + individualShape.TextFrame.TextRange.Text
On Error GoTo 0
If individualShape.HasSmartArt Then
For Each individualSmartArtNode In individualShape.SmartArt.AllNodes
allStrings = allStrings + individualSmartArtNode.TextFrame2.TextRange.Text
Next
End If
If individualShape.HasChart Then
If individualShape.Chart.HasTitle Then
allStrings = allStrings + individualShape.Chart.ChartTitle.Text
End If
End If
On Error Resume Next
For Each individualRow In individualShape.Table.Rows
For Each individualCell In individualRow.Cells
allStrings = allStrings + individualCell.Shape.TextFrame.TextRange.Text
Next
Next
On Error GoTo 0
Next
For Each individualCustomLayout In individualDesign.SlideMaster.CustomLayouts
For Each individualShape In individualCustomLayout.Shapes
On Error Resume Next
allStrings = allStrings + individualShape.TextFrame.TextRange.Text
On Error GoTo 0
If individualShape.HasSmartArt Then
For Each individualSmartArtNode In individualShape.SmartArt.AllNodes
allStrings = allStrings + individualSmartArtNode.TextFrame2.TextRange.Text
Next
End If
If individualShape.HasChart Then
If individualShape.Chart.HasTitle Then
allStrings = allStrings + individualShape.Chart.ChartTitle.Text
End If
End If
On Error Resume Next
For Each individualRow In individualShape.Table.Rows
For Each individualCell In individualRow.Cells
allStrings = allStrings + individualCell.Shape.TextFrame.TextRange.Text
Next
Next
On Error GoTo 0
Next
Next
Next
GetAllText = allStrings
End Function
Private Function ParseOutTemplates( ByVal allStrings$)
Dim Regex As Object
Set Regex = CreateObject("VBScript.RegExp")
With Regex
.Global = True
.IgnoreCase = True
.MultiLine = True
.Pattern = "\{\{.*?\}\}"
End With
Dim individualMatch
Dim individualStringTemplate$
Dim regexMatches
Set regexMatches = Regex.Execute(allStrings)
Dim templateDictionary As Object
Set templateDictionary = CreateObject("Scripting.Dictionary")
For Each individualMatch In regexMatches
individualStringTemplate = individualMatch.Value
individualStringTemplate = Mid(individualStringTemplate, 3, Len(individualStringTemplate) - 4)
individualStringTemplate = Trim(individualStringTemplate)
If InStr(1, individualStringTemplate, "{") Or InStr(1, individualStringTemplate, "}") Then
MsgBox "Error, missing curly brace '{' or '}' on one of the templates:" & vbCrLf & vbCrLf & individualMatch.Value, Title:="Template Syntax Error"
Exit Function
End If
If InStr(1, individualStringTemplate, "\") Then
If Not templateDictionary.Exists(individualMatch.Value) Then
templateDictionary.Add individualMatch.Value, individualStringTemplate
End If
Else
If Not templateDictionary.Exists(individualMatch.Value) Then
templateDictionary.Add individualMatch.Value, ActivePresentation.Path & "\" & individualStringTemplate
End If
End If
Next
Set ParseOutTemplates = templateDictionary
End Function
Private Function FetchExcelData( ByVal templateDictionary)
Dim ExcelApplication As Object
Set ExcelApplication = CreateObject("Excel.Application")
Dim currentWorkbook
ExcelApplication.Visible = False
Dim workbookPathDictionary As Object
Set workbookPathDictionary = CreateObject("Scripting.Dictionary")
Dim fetchTemplate
Dim fullRangeDetails$
Dim workbookPath$
Dim workbookName$
Dim sheetName$
Dim rangeAddress$
For Each fetchTemplate In templateDictionary.Keys()
fullRangeDetails = Right(templateDictionary(fetchTemplate), Len(templateDictionary(fetchTemplate)) - InStrRev(templateDictionary(fetchTemplate), "\"))
workbookName = Left(fullRangeDetails, InStrRev(fullRangeDetails, "]") - 1)
workbookName = Mid(workbookName, 2)
workbookPath = Left(templateDictionary(fetchTemplate), InStrRev(templateDictionary(fetchTemplate), "\")) & workbookName
If Not workbookPathDictionary.Exists(workbookPath) Then
workbookPathDictionary.Add workbookPath, New Collection
workbookPathDictionary.Item(workbookPath).Add templateDictionary(fetchTemplate)
Else
workbookPathDictionary.Item(workbookPath).Add templateDictionary(fetchTemplate)
End If
Next
Dim workbookPathKey
Dim modifiedTemplateDictionary As Object
Set modifiedTemplateDictionary = CreateObject("Scripting.Dictionary")
For Each workbookPathKey In workbookPathDictionary.Keys()
For Each fetchTemplate In workbookPathDictionary(workbookPathKey)
fullRangeDetails = Right(fetchTemplate, Len(fetchTemplate) - InStrRev(fetchTemplate, "\"))
workbookName = Left(fullRangeDetails, InStrRev(fullRangeDetails, "]") - 1)
workbookName = Mid(workbookName, 2)
workbookPath = Left(fetchTemplate, InStrRev(fetchTemplate, "\")) & workbookName
sheetName = Mid(fullRangeDetails, InStrRev(fullRangeDetails, "]") + 1)
sheetName = Left(sheetName, InStrRev(sheetName, "!") - 1)
rangeAddress = Right(fullRangeDetails, Len(fullRangeDetails) - InStrRev(fullRangeDetails, "!"))
rangeAddress = Replace(rangeAddress, "$", "")
If Not modifiedTemplateDictionary.Exists(fetchTemplate) Then
Set currentWorkbook = ExcelApplication.Workbooks.Open(workbookPath)
modifiedTemplateDictionary.Add fetchTemplate, currentWorkbook.Sheets(sheetName).Range(rangeAddress).Value
currentWorkbook.Close False
Set currentWorkbook = Nothing
End If
Next
Next
Dim templateKey
For Each templateKey In templateDictionary.Keys()
templateDictionary(templateKey) = modifiedTemplateDictionary(templateDictionary(templateKey))
Next
Set ExcelApplication = Nothing
Set FetchExcelData = templateDictionary
End Function
Private Sub ReplaceTemplatesWithValues( ByVal templateDictionary)
Dim individualSlide As Slide
Dim individualShape As Shape
Dim individualSmartArtNode As SmartArtNode
Dim individualRow As Row
Dim individualCell As Cell
Dim individualDesign As Design
Dim individualCustomLayout As CustomLayout
Dim templateKey
For Each templateKey In templateDictionary.Keys()
For Each individualSlide In ActivePresentation.Slides
For Each individualShape In individualSlide.Shapes
On Error Resume Next
individualShape.TextFrame.TextRange.Replace templateKey, templateDictionary(templateKey)
On Error GoTo 0
If individualShape.HasSmartArt Then
For Each individualSmartArtNode In individualShape.SmartArt.AllNodes
individualSmartArtNode.TextFrame2.TextRange.Replace templateKey, templateDictionary(templateKey)
Next
End If
If individualShape.HasChart Then
If individualShape.Chart.HasTitle Then
individualShape.Chart.ChartTitle.Text = Replace(individualShape.Chart.ChartTitle.Text, templateKey, templateDictionary(templateKey))
End If
End If
On Error Resume Next
For Each individualRow In individualShape.Table.Rows
For Each individualCell In individualRow.Cells
individualCell.Shape.TextFrame.TextRange.Replace templateKey, templateDictionary(templateKey)
Next
Next
On Error GoTo 0
Next
On Error Resume Next
individualSlide.HeadersFooters.Header.Text = Replace(individualSlide.HeadersFooters.Header.Text, templateKey, templateDictionary(templateKey))
On Error GoTo 0
On Error Resume Next
individualSlide.HeadersFooters.Footer.Text = Replace(individualSlide.HeadersFooters.Footer.Text, templateKey, templateDictionary(templateKey))
On Error GoTo 0
Next
For Each individualDesign In ActivePresentation.Designs
For Each individualShape In individualDesign.SlideMaster.Shapes
On Error Resume Next
individualShape.TextFrame.TextRange.Replace templateKey, templateDictionary(templateKey)
On Error GoTo 0
If individualShape.HasSmartArt Then
For Each individualSmartArtNode In individualShape.SmartArt.AllNodes
individualSmartArtNode.TextFrame2.TextRange.Replace templateKey, templateDictionary(templateKey)
Next
End If
If individualShape.HasChart Then
If individualShape.Chart.HasTitle Then
individualShape.Chart.ChartTitle.Text = Replace(individualShape.Chart.ChartTitle.Text, templateKey, templateDictionary(templateKey))
End If
End If
On Error Resume Next
For Each individualRow In individualShape.Table.Rows
For Each individualCell In individualRow.Cells
individualCell.Shape.TextFrame.TextRange.Replace templateKey, templateDictionary(templateKey)
Next
Next
On Error GoTo 0
Next
For Each individualCustomLayout In individualDesign.SlideMaster.CustomLayouts
For Each individualShape In individualCustomLayout.Shapes
On Error Resume Next
individualShape.TextFrame.TextRange.Replace templateKey, templateDictionary(templateKey)
On Error GoTo 0
If individualShape.HasSmartArt Then
For Each individualSmartArtNode In individualShape.SmartArt.AllNodes
individualSmartArtNode.TextFrame2.TextRange.Replace templateKey, templateDictionary(templateKey)
Next
End If
If individualShape.HasChart Then
If individualShape.Chart.HasTitle Then
individualShape.Chart.ChartTitle.Text = Replace(individualShape.Chart.ChartTitle.Text, templateKey, templateDictionary(templateKey))
End If
End If
On Error Resume Next
For Each individualRow In individualShape.Table.Rows
For Each individualCell In individualRow.Cells
individualCell.Shape.TextFrame.TextRange.Replace templateKey, templateDictionary(templateKey)
Next
Next
On Error GoTo 0
Next
Next
Next
Next
End Sub
Public Sub XTemplate()
Dim allStrings$
allStrings = GetAllText()
Dim origionalTemplateDictionary
Set origionalTemplateDictionary = ParseOutTemplates(allStrings)
Dim templateDictionary
Set templateDictionary = FetchExcelData(origionalTemplateDictionary)
ReplaceTemplatesWithValues templateDictionary
End Sub