twb 3.9.3 → 3.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/twb.rb +6 -2
- data/lib/twb/analysis/DataSources/parametersanalyzer.rb +95 -0
- data/lib/twb/analysis/Sheets/sheetfiltersanalyzer.rb +18 -309
- data/lib/twb/analysis/Sheets/sheetfiltersanalyzerA.rb +81 -0
- data/lib/twb/calculatedfield.rb +3 -1
- data/lib/twb/datasource.rb +26 -3
- data/lib/twb/groupfield.rb +55 -0
- data/lib/twb/parameter.rb +119 -0
- data/lib/twb/quickfilter.rb +442 -0
- data/lib/twb/tabtool.rb +13 -4
- data/lib/twb/workbook.rb +26 -5
- data/lib/twb/worksheet.rb +28 -4
- metadata +7 -6
- data/LICENSE.md +0 -1
- data/LICENSE.txt +0 -619
- data/README.md +0 -32
- data/lib/twb/dashboard.txt +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a3bca661db5662df120e34443a68874a5a0d5f6
|
4
|
+
data.tar.gz: 56e2f1171c7c4df1b64a6f4767070ecb9f023b76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85fc520db33e97945985b457870f21f73ced2105ba7b60287ccefb09291292da2969f364a771d9d6283abd8b00b61a58f43864500dc8fd5c7e19fcfc1a73a1f4
|
7
|
+
data.tar.gz: 55834df4440a51aad3c9ed05aa069c961365aafa56254aaf99a59cd64734cdbf0c8ca1aa3cd9e5d64fbce7883380ebf116d4ee9ffbd58ac414dddb6fac2f6be2
|
data/lib/twb.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2014, 2015 Chris Gerrard
|
1
|
+
# Copyright (C) 2014, 2015, 2018 Chris Gerrard
|
2
2
|
#
|
3
3
|
# This program is free software: you can redistribute it and/or modify
|
4
4
|
# it under the terms of the GNU General Public License as published by
|
@@ -25,11 +25,14 @@ require_relative 'twb/storyboard'
|
|
25
25
|
require_relative 'twb/window'
|
26
26
|
require_relative 'twb/workbook'
|
27
27
|
require_relative 'twb/worksheet'
|
28
|
+
require_relative 'twb/parameter'
|
28
29
|
require_relative 'twb/action'
|
29
30
|
require_relative 'twb/columnfield.rb'
|
30
31
|
require_relative 'twb/calculatedfield'
|
31
32
|
require_relative 'twb/codedfield'
|
33
|
+
require_relative 'twb/groupfield'
|
32
34
|
require_relative 'twb/fieldcalculation'
|
35
|
+
require_relative 'twb/quickfilter'
|
33
36
|
require_relative 'twb/docdashboardimagevert'
|
34
37
|
require_relative 'twb/docdashboardwebvert'
|
35
38
|
require_relative 'twb/util/twbDashSheetDataDotBuilder'
|
@@ -54,6 +57,7 @@ require_relative 'twb/analysis/calculatedfields/csvemitter'
|
|
54
57
|
require_relative 'twb/analysis/datasources/DataSourceFieldsCSVEmitter'
|
55
58
|
require_relative 'twb/analysis/datasources/DataSourceTableFieldsCSVEmitter'
|
56
59
|
require_relative 'twb/analysis/datasources/googlesheetdatasourcesanalyzer'
|
60
|
+
require_relative 'twb/analysis/datasources/parametersanalyzer'
|
57
61
|
require_relative 'twb/analysis/Sheets/WorksheetDataStructureCSVEmitter'
|
58
62
|
require_relative 'twb/analysis/Sheets/sheetfiltersanalyzer'
|
59
63
|
require_relative 'twb/analysis/Sheets/sheetfieldsanalyzer'
|
@@ -63,5 +67,5 @@ require_relative 'twb/analysis/Sheets/dashsheetsanalyzer'
|
|
63
67
|
# Represents Tableau Workbooks and their contents.
|
64
68
|
#
|
65
69
|
module Twb
|
66
|
-
VERSION = '3.9.
|
70
|
+
VERSION = '3.9.7'
|
67
71
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# sheetfieldsanalyzer.rb Copyright (C) 2018 Chris Gerrard
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require 'twb'
|
17
|
+
require 'csv'
|
18
|
+
# require 'set'
|
19
|
+
|
20
|
+
module Twb
|
21
|
+
module Analysis
|
22
|
+
|
23
|
+
class ParametersAnalyzer
|
24
|
+
|
25
|
+
include TabTool
|
26
|
+
|
27
|
+
attr_accessor :localEmit
|
28
|
+
attr_reader :twbname, :twbcount
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
init
|
32
|
+
#-- set up metrics
|
33
|
+
@paramscount = 0
|
34
|
+
#--
|
35
|
+
@funcdoc = {:class=>self.class, :blurb=>'Analyzing Parameters from Tableau Workbooks.', :description=>nil,}
|
36
|
+
docFileName = docFile('TWBParameters.csv')
|
37
|
+
@csv = CSV.open(docFileName, 'w')
|
38
|
+
@csv << ["Workbook",'Parameter','Caption','Name (tech)','Type','Format','Type (custom)','Type (domain)','Role', 'Value (current)', 'Value','Value (tech)']
|
39
|
+
# [ @twbname, name, caption, nameTech, type, format, typeCustom, domainType, role]
|
40
|
+
@docfiles = [{:name=>docFileName,:description=>"CSV File containing the data relevant for Parameters."}]
|
41
|
+
end
|
42
|
+
|
43
|
+
#-- Parameter attributes
|
44
|
+
# caption : 11
|
45
|
+
# name : 11
|
46
|
+
# datatype : 11
|
47
|
+
# datatype-customized : 9
|
48
|
+
|
49
|
+
# param-domain-type : 11
|
50
|
+
# role : 11
|
51
|
+
# type : 11
|
52
|
+
# value : 11
|
53
|
+
# default-format : 7
|
54
|
+
# alias : 1
|
55
|
+
|
56
|
+
def processTWB twb
|
57
|
+
if Twb::Workbook != twb.class
|
58
|
+
@twb = Twb::Workbook.new twb
|
59
|
+
else
|
60
|
+
@twb = twb
|
61
|
+
end
|
62
|
+
@twbname = @twb.name
|
63
|
+
emit "Workbook:: #{@twbname}"
|
64
|
+
paramsDS = @twb.datasource 'Parameters'
|
65
|
+
@twb.parameters.each do |pName,param|
|
66
|
+
@paramscount += 1
|
67
|
+
param.values.each do |values|
|
68
|
+
@csv << [ @twbname,
|
69
|
+
param.uiname,
|
70
|
+
param.caption,
|
71
|
+
param.name,
|
72
|
+
param.type,
|
73
|
+
param.format,
|
74
|
+
param.dataTypeCustom,
|
75
|
+
param.domainType,
|
76
|
+
param.role,
|
77
|
+
param.currentValue, # 'Value (current)',
|
78
|
+
values[:value], # 'Value',
|
79
|
+
values[:valueTech] # 'Value (tech)'
|
80
|
+
]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def metrics
|
86
|
+
{
|
87
|
+
'# of Parameters' => @paramscount,
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
end #class ParametersAnalyzer
|
92
|
+
|
93
|
+
end # module Analysis
|
94
|
+
|
95
|
+
end # module Twb
|
@@ -29,344 +29,53 @@ module Analysis
|
|
29
29
|
init
|
30
30
|
@funcdoc = {:class=>self.class, :blurb=>'Analyze Worksheet filters.', :description=>'Documents Quick Filters and the values they employ, if any. Work in progess.',}
|
31
31
|
#--
|
32
|
-
docFileName = docFile('
|
32
|
+
docFileName = docFile('WorksheetFilters.csv')
|
33
33
|
$sheetFieldsCSV = CSV.open( docFileName ,'w')
|
34
|
-
$sheetFieldsCSV << ['Workbook','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?']
|
34
|
+
$sheetFieldsCSV << ['Workbook','Worksheet','Filter Type','Operation','Data Source','Field','Value','Alias', 'Alias?','Operation Mode','Include Null?']
|
35
35
|
addDocFile docFileName, "Workbooks, Worksheets and the sheets' Quick Filters"
|
36
36
|
#--
|
37
|
-
@twbCount = 0
|
38
37
|
@sheetCount = 0
|
39
38
|
@filterCount = 0
|
40
39
|
end
|
41
40
|
|
42
41
|
def metrics
|
43
42
|
{
|
44
|
-
'# of Workbooks' => @twbcount,
|
45
43
|
'# of Worksheets' => @sheetCount,
|
46
44
|
'# of Worksheet Filters' => @filterCount
|
47
45
|
}
|
48
46
|
end
|
49
47
|
|
50
48
|
def processTWB twb
|
51
|
-
@twb
|
52
|
-
|
53
|
-
|
49
|
+
@twb = twb
|
50
|
+
@twbName = @twb.name
|
51
|
+
emit " -- #{@twbName}"
|
54
52
|
@twbDomainsLoaded = false
|
55
53
|
parseFilters
|
56
|
-
finis
|
57
54
|
end
|
58
55
|
|
59
|
-
|
60
56
|
def parseFilters
|
61
57
|
@worksheets = @twb.worksheets
|
62
58
|
@worksheets.each do |sheet|
|
63
59
|
emit "\n\nSHEET: #{sheet.name}"
|
64
|
-
|
65
|
-
filters = sheet.node.xpath('.//filter[@column]')
|
60
|
+
filters = sheet.filters
|
66
61
|
filters.each do |filter|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
codedField = Twb::CodedField.new(fieldCode)
|
72
|
-
fieldTech = codedField.name
|
73
|
-
inexclude = fieldTech =~ /^(Ex|In)clusions/
|
74
|
-
measureNames = ':Measure Names' == fieldTech
|
75
|
-
srcTech = codedField.dataSource
|
76
|
-
dataSource = @twb.datasource(srcTech)
|
77
|
-
@dsAliases = dataSource.aliases
|
78
|
-
field = measureNames || inexclude ? fieldTech : dataSource.field(fieldTech)
|
79
|
-
fieldName = measureNames || inexclude ? fieldTech : dataSource.fieldUIName(fieldTech)
|
80
|
-
emit "\n:: FIELD :: #{field} == #{fieldName} -- #{fieldTech} -- #{codedField.rawCode}"
|
81
|
-
emit " filter class: #{filterClass}"
|
82
|
-
emit " field code: #{fieldCode}"
|
83
|
-
emit " coded field: #{codedField}"
|
84
|
-
emit " field tech: #{fieldTech}"
|
85
|
-
emit " field name: nil? #{fieldName.nil?} #{fieldName} "
|
86
|
-
emit " src tech: #{srcTech}"
|
87
|
-
emit " measureNames: #{measureNames}"
|
88
|
-
emit " sheet: #{sheet.name}"
|
89
|
-
emit " node: #{filter}"
|
90
|
-
emit " ds: #{dataSource.uiname}"
|
91
|
-
emit " field: #{field}"
|
92
|
-
emit " "
|
93
|
-
aaa = case filterClass
|
94
|
-
when 'relative-date' then resolveRelativeDate(sheet, dataSource, fieldName, filter)
|
95
|
-
when 'quantitative' then resolveQuantitative(sheet, dataSource, fieldName, filter)
|
96
|
-
when 'categorical' then resolveCategoricalValues(sheet, dataSource, fieldName, filter, measureNames)
|
62
|
+
filter.emit "-----------------------------\nWORKSHEET:: #{sheet.name}\n-----------------------------"
|
63
|
+
if filter.values.empty?
|
64
|
+
# $sheetFieldsCSV << ['Workbook','Worksheet','Filter Type','Operation' ,'Data Source','Field','Value','Alias', 'Alias?']
|
65
|
+
$sheetFieldsCSV << [@twbName ,sheet.name, filter.type ,filter.inexclude, filter.dataSource.uiname, filter.uiname,nil,nil,nil,filter.inexMode,filter.includeNull]
|
97
66
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-1' include-future='true' include-null='false' last-period='0' period-type='year' />
|
105
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-2' include-future='true' include-null='false' last-period='0' period-type='day' />
|
106
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-2' include-future='true' include-null='false' last-period='0' period-type='year' />
|
107
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-6' include-future='true' include-null='false' last-period='0' period-type='day' />
|
108
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='false' include-null='false' last-period='0' period-type='year' />
|
109
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='0' period-type='day' />
|
110
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='0' period-type='year' />
|
111
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='2' period-type='day' />
|
112
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='2' period-type='year' />
|
113
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='4' period-type='day' />
|
114
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='1' include-future='true' include-null='false' last-period='1' period-type='day' />
|
115
|
-
# filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='1' include-future='true' include-null='false' last-period='1' period-type='year' />
|
116
|
-
def resolveRelativeDate sheet, dataSource, field, node
|
117
|
-
emit "resolveRelativeDate"
|
118
|
-
operation = 'Inclusive'
|
119
|
-
periodType = node['period-type']
|
120
|
-
inclFuture = node['include-future'] == 'true'
|
121
|
-
firstPeriod = node['first-period'].to_i
|
122
|
-
lastPeriod = node['last-period'].to_i
|
123
|
-
sum = firstPeriod + lastPeriod
|
124
|
-
prod = firstPeriod * lastPeriod
|
125
|
-
periodTech = "#{periodType} : #{firstPeriod} -> #{lastPeriod}"
|
126
|
-
period = periodTech
|
127
|
-
if sum == 0 && prod == 0
|
128
|
-
period = case periodType
|
129
|
-
when 'day' then "Today"
|
130
|
-
else inclFuture ? "This #{periodType.capitalize}" : "#{periodType.capitalize} to date"
|
131
|
-
end
|
132
|
-
elsif firstPeriod == lastPeriod
|
133
|
-
future = firstPeriod > 0
|
134
|
-
reln = future ? 'Next' : 'Previous'
|
135
|
-
period = case periodType
|
136
|
-
when 'day' then future ? 'Tomorrow' : 'Yesterday'
|
137
|
-
else "#{reln} #{periodType.capitalize}"
|
138
|
-
end
|
139
|
-
else
|
140
|
-
span = lastPeriod - firstPeriod + 1
|
141
|
-
future = firstPeriod == 0
|
142
|
-
reln = future ? "Next" : "Last"
|
143
|
-
period = "#{reln} #{span} #{periodType.capitalize}s"
|
144
|
-
end
|
145
|
-
$sheetFieldsCSV << [ @twb.name, sheet.name, 'Relative Date',operation, dataSource.uiname, field, period, periodTech ]
|
146
|
-
end
|
147
|
-
|
148
|
-
# <filter class='quantitative' column='[Sample - Superstore].[none:Profit:qk]' included-values='in-range'>
|
149
|
-
# <filter class='quantitative' column='[Sample - Superstore].[none:Profit:qk]' included-values='in-range'>
|
150
|
-
# <filter class='quantitative' column='[Sample - Superstore].[none:Profit:qk]' included-values='in-range'>
|
151
|
-
# <filter class='quantitative' column='[Sample - Superstore].[none:Profit:qk]' included-values='all' />
|
152
|
-
# <filter class='quantitative' column='[Sample - Superstore].[none:Profit:qk]' included-values='non-null' />
|
153
|
-
# <filter class='quantitative' column='[Sample - Superstore].[none:Profit:qk]' included-values='null' />
|
154
|
-
def resolveQuantitative sheet, dataSource, field, node
|
155
|
-
emit "resolveQuantitative"
|
156
|
-
operation = 'Inclusive'
|
157
|
-
inclValues = node['included-values']
|
158
|
-
values = if 'in-range' == inclValues
|
159
|
-
quantRangeValues node
|
160
|
-
else
|
161
|
-
"#{inclValues.capitalize} Values"
|
162
|
-
end
|
163
|
-
$sheetFieldsCSV << [ @twb.name, sheet.name, 'Range (row)',operation.capitalize, dataSource.uiname, field, values, inclValues ]
|
164
|
-
end
|
165
|
-
|
166
|
-
def quantRangeValues node
|
167
|
-
min = node.at_xpath('min')
|
168
|
-
max = node.at_xpath('max')
|
169
|
-
emit "min: nil? %-6s val: %-s " % [min.nil?,min]
|
170
|
-
emit "max: nil? %-6s val: %-s " % [max.nil?,max]
|
171
|
-
minrv = parseRangeVal min unless min.nil?
|
172
|
-
maxrv = parseRangeVal max unless max.nil?
|
173
|
-
mintxt = min.nil? ? '' : max.nil? ? "At least: #{minrv}" : "Range #{minrv}"
|
174
|
-
maxtxt = max.nil? ? '' : min.nil? ? "At most: #{maxrv}" : " ... #{maxrv}"
|
175
|
-
emit "#{mintxt} #{maxtxt}"
|
176
|
-
return "#{mintxt} #{maxtxt}"
|
177
|
-
end
|
178
|
-
|
179
|
-
def parseRangeVal node
|
180
|
-
return 'nil' if node.nil?
|
181
|
-
text = node.text
|
182
|
-
if text.start_with?('#')
|
183
|
-
return text.gsub(/^[#]|[#]$/,'')
|
184
|
-
end
|
185
|
-
num = text.to_f
|
186
|
-
# num.negative? ? num.floor : num.ceil
|
187
|
-
result = if num < 0
|
188
|
-
num.floor
|
189
|
-
else
|
190
|
-
num.ceil
|
191
|
-
end
|
192
|
-
return result
|
193
|
-
end
|
194
|
-
|
195
|
-
def resolveCategoricalValues sheet, dataSource, field, node, measureNames
|
196
|
-
emit "resolveCategoricalValues"
|
197
|
-
emit "measureNames: #{measureNames}"
|
198
|
-
firstChild = node.at_xpath('./groupfilter')
|
199
|
-
results = {}
|
200
|
-
#-- handling Inclusions & Exclusions, in-sheet pick-data filters
|
201
|
-
if field =~ /^(Ex|In)clusions/
|
202
|
-
enumerate = firstChild['user:ui-enumeration']
|
203
|
-
operation = enumerate.nil? ? 'Inclusive' : enumerate.capitalize
|
204
|
-
$sheetFieldsCSV << [ @twb.name, sheet.name, 'In-Sheet', operation, dataSource.uiname, field, '+++', '+++' ]
|
205
|
-
return results
|
206
|
-
end
|
207
|
-
#--
|
208
|
-
unless firstChild.nil?
|
209
|
-
function = firstChild.attribute('function').text
|
210
|
-
enumerate = firstChild['user:ui-enumeration']
|
211
|
-
operation = enumerate.nil? ? 'Inclusive' : enumerate.capitalize
|
212
|
-
emit "function : #{function}"
|
213
|
-
emit "enumerate: #{enumerate}"
|
214
|
-
emit "operation: #{operation}"
|
215
|
-
emit node.to_s
|
216
|
-
#-- single element filter
|
217
|
-
if 'member'.eql? function
|
218
|
-
emit "HANDLING SINGLE MEMBER FILTER"
|
219
|
-
member = firstChild['member']
|
220
|
-
value = measureNames ? dataSource.fieldUIName(Twb::CodedField.new(member).name) : member.gsub(/^"|"$/,'')
|
221
|
-
alia = dataSource.deAlias(field,value)
|
222
|
-
emit "value :%-25s => alias: %-s" % [value, alia]
|
223
|
-
$sheetFieldsCSV << [ @twb.name, sheet.name, 'single', operation, dataSource.uiname, field, value, alia ]
|
224
|
-
return {value => alia}
|
225
|
-
end
|
226
|
-
#-- another single element filter
|
227
|
-
# <groupfilter function="level-members" level="[none:Business Line:nk]" user:ui-enumeration="all" user:ui-marker="enumerate"/>
|
228
|
-
# <filter class='categorical' column='[federated.1astm0q1hl2ydc1dyqhqq0igvxkp].[none:Business Line:nk]' context='true'>
|
229
|
-
# <groupfilter function='level-members'
|
230
|
-
# level='[none:Business Line:nk]'
|
231
|
-
# user:ui-enumeration='all'
|
232
|
-
# user:ui-exclude='true'
|
233
|
-
# user:ui-marker='enumerate' />
|
234
|
-
# </filter>
|
235
|
-
# <filter class='categorical' column='[federated.1astm0q1hl2ydc1dyqhqq0igvxkp].[none:Business Line:nk]' context='true'>
|
236
|
-
# <groupfilter function='level-members'
|
237
|
-
# level='[none:Business Line:nk]'
|
238
|
-
# user:ui-enumeration='all'
|
239
|
-
# user:ui-marker='enumerate' />
|
240
|
-
# </filter>
|
241
|
-
if 'level-members'.eql? function
|
242
|
-
emit "HANDLING level-members FILTER"
|
243
|
-
inclorexcl = firstChild.has_attribute?('user:ui-exclude') ? 'Exclusive' : 'Inclusive'
|
244
|
-
$sheetFieldsCSV << [ @twb.name, sheet.name, 'single', inclorexcl, dataSource.uiname, field, operation, enumerate ]
|
245
|
-
end
|
246
|
-
#-- otherwise filter contains multiple elements
|
247
|
-
#-- handle individual member elements
|
248
|
-
elements = firstChild.xpath('.//groupfilter')
|
249
|
-
elements.each do |element|
|
250
|
-
function = element.attribute('function').text
|
251
|
-
emit "element function: #{function}\n node:\n#{element}"
|
252
|
-
if 'member'.eql? function
|
253
|
-
member = element.attribute('member').text
|
254
|
-
name = measureNames ? dataSource.fieldUIName(Twb::CodedField.new(member).name) : member.gsub(/^"|"$/,'')
|
255
|
-
emit "%%%% member NAME:: #{name}"
|
256
|
-
if '%null%' == name then name = 'Null' end
|
257
|
-
alia = dataSource.fieldAlias(field,name) # $TableNameAliases[name]
|
258
|
-
results[name] = alia
|
259
|
-
end
|
260
|
-
if 'range'.eql? function
|
261
|
-
emit "%%%% range element:: #{element}"
|
262
|
-
t = filtersFromRangeNode(dataSource, field, element)
|
263
|
-
|
264
|
-
if t.empty?
|
265
|
-
from = element['from']
|
266
|
-
to = element['to']
|
267
|
-
range = "#{from} ... #{to}"
|
268
|
-
results[range] = range
|
269
|
-
end
|
270
|
-
|
271
|
-
t.each do |name,alia|
|
272
|
-
emit "%%%% range Name: %-20s ALIAS: %-s " % [name, alia]
|
273
|
-
results[name] = dataSource.fieldAlias(field,name)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
results.each do |name,alia|
|
278
|
-
$sheetFieldsCSV << [ @twb.name, sheet.name, 'single',operation, dataSource.uiname, field, name, alia, !name.eql?(alia) ]
|
279
|
-
end
|
280
|
-
end
|
281
|
-
return results
|
282
|
-
end
|
283
|
-
|
284
|
-
def processMeasureNames sheet, dataSource, field, node
|
285
|
-
emit 'processMeasureNames'
|
286
|
-
end
|
287
|
-
|
288
|
-
def filtersFromRangeNode dataSource, field, node
|
289
|
-
unless @twbDomainsLoaded
|
290
|
-
loadDomains
|
291
|
-
end
|
292
|
-
emit "filtersFromRangeNode"
|
293
|
-
emit " from: #{node.attribute('from')}"
|
294
|
-
emit " to. : #{node.attribute('to')}"
|
295
|
-
from = node.attribute('from').text.gsub(/^"|"$/,'')
|
296
|
-
to = node.attribute( 'to').text.gsub(/^"|"$/,'')
|
297
|
-
emit " from: #{from}"
|
298
|
-
emit " to. : #{to}"
|
299
|
-
filtersInRange dataSource, field, from, to
|
300
|
-
end
|
301
|
-
|
302
|
-
def filtersInRange dataSource, field, from, to
|
303
|
-
emit "filtersInRange"
|
304
|
-
results = {}
|
305
|
-
dsFields = @twbFielddomains[dataSource.uiname]
|
306
|
-
emit "dsFields : #{dsFields}"
|
307
|
-
if dsFields.nil? || dsFields.empty?
|
308
|
-
alert "#### ALERT #### - '#{field}' FIELD DOMAIN VALUES FOR '#{@twb.name} DATASOURCE #{dataSource.uiname} NOT LOADED ####"
|
309
|
-
emit @twbFieldDomains
|
310
|
-
emit "==========="
|
311
|
-
emit dsFields
|
312
|
-
emit "==========="
|
313
|
-
else
|
314
|
-
fieldVals = dsFields[field].to_a
|
315
|
-
if dataSource.fieldHasAliases field
|
316
|
-
#-- resolve aliases
|
317
|
-
dbValues = SortedSet.new
|
318
|
-
aliases = dataSource.fieldAliases field
|
319
|
-
fieldVals.each do |fv|
|
320
|
-
fvAliased = aliases.has_value? fv
|
321
|
-
if fvAliased
|
322
|
-
dbValues << aliases.key(fv)
|
323
|
-
else
|
324
|
-
dbValues << fv
|
325
|
-
end
|
326
|
-
end
|
327
|
-
$fieldVals = dbValues.to_a
|
328
|
-
else
|
329
|
-
#-- use domain values as returned
|
330
|
-
$fieldVals = dsFields[field].to_a
|
331
|
-
end
|
332
|
-
# domainVals = dsFields[field].to_a
|
333
|
-
# #-- need to dealias (unalias?) the field domain values
|
334
|
-
# dbVals = SortedSet.new
|
335
|
-
# domainVals.each do |dv|
|
336
|
-
emit "field values: #{$fieldVals}"
|
337
|
-
unless $fieldVals.nil? || $fieldVals.empty?
|
338
|
-
values = $fieldVals
|
339
|
-
f_i = values.index from
|
340
|
-
t_i = values.index to
|
341
|
-
emit " from: #{f_i} :: '#{from}'"
|
342
|
-
emit " to: #{t_i} :: '#{to}'"
|
343
|
-
badRange = f_i.nil? || t_i.nil?
|
344
|
-
emit "badRange: #{badRange}"
|
345
|
-
if badRange
|
346
|
-
emit "BAD RANGE"
|
347
|
-
else
|
348
|
-
tnames = values[f_i..t_i]
|
349
|
-
tnames.each do |tname|
|
350
|
-
results[tname] = dataSource.deAlias(field,tname) # $TableNameAliases[tname]
|
351
|
-
end
|
352
|
-
emit " filtersInRange f:%-35s t:%-s " % ["'#{from}:#{f_i}'", "'#{to}:#{t_i}'"]
|
353
|
-
emit " names: #{results.keys}"
|
354
|
-
emit " aliases: #{results.values}"
|
355
|
-
end
|
67
|
+
filter.values.each do |valueMap|
|
68
|
+
value = valueMap[:value]
|
69
|
+
valias = valueMap[:alias]
|
70
|
+
same = value.eql? valias
|
71
|
+
# puts "RECORDING FILTER VALUES: %-25s -- %-25s same? %s " % [value,valias,same]
|
72
|
+
$sheetFieldsCSV << [@twbName ,sheet.name, filter.type ,filter.inexclude, filter.dataSource.uiname, filter.uiname, value, valias, same,filter.inexMode,filter.includeNull]
|
356
73
|
end
|
74
|
+
end
|
357
75
|
end
|
358
|
-
return results
|
359
|
-
end
|
360
|
-
|
361
|
-
def loadDomains
|
362
|
-
emit "def loadDomains\n=="
|
363
|
-
loader = Twb::Util::FieldDomainLoader.new
|
364
|
-
@twbFielddomains = loader.loadWorkbook @twb
|
365
|
-
emit "FIELD DOMAINS:: #{@twbFielddomains}\n=="
|
366
|
-
@twbDomainsLoaded = true
|
367
76
|
end
|
368
77
|
|
369
|
-
end # class
|
78
|
+
end # class SheetFiltersAnalyzerA
|
370
79
|
|
371
80
|
end # module Twb
|
372
81
|
end # module Analysis
|