twb 3.9.3 → 3.9.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|