数据交叉表的实现(2):通过组建Axes轴和Cell数组来建立数据交叉表模型
这篇距离上篇已经有些时日了,最近也比较忙,一直没有好好的整理
楼下有人要代码,我就发出来把。顺便做个简单的介绍
模型的建立
横轴:
竖轴:
因为两个轴是一样的,那么我们放在一起来讲
首先一个轴应该包含哪些信息呢?
1:轴名称
2:Positon集合(用于存放真正的维度信息)
每个轴都有若干个Position 一个Position代表一个维度,Position里面是Member的结合(也就是维度数据的集合)--如下图所示:
数据CellSet:
CellSet相对前面的概念来说就比较简单了,Cellset就是存放数据的容器了
其中一个单元格就是一个Cell
我们还是来看一下代码把
数据绑定的部分
1
绑定数据#region 绑定数据
2
private DataView _dataView;
3
public override void DataBind()
4
{
5
// Load the data 其中dataSource是已经绑定的数据源
6
if (_dataSource != null)
7
{
8
if (_dataSource is DataView || _dataSource is DataSet || _dataSource is DataTable)
9
{
10
if (_dataSource is DataView)
11
{
12
_dataView = (DataView)_dataSource;
13
}
14
else if (_dataSource is DataSet)
15
{
16
_dataView = ((DataSet)_dataSource).Tables[0].DefaultView;
17
}
18
else // DataTable
19
{
20
_dataView = ((DataTable)_dataSource).DefaultView;
21
}
22
23
this.DataBindToDataView(_dataView);
24
}
25
else if (_dataSource is IEnumerable)
26
{
27
this.DataBindToEnumerable((IEnumerable)_dataSource);
28
}
29
else
30
{
31
throw new Exception("Cannot bind to data source of type " + _dataSource.GetType().ToString());
32
}
33
}
34
35
base.DataBind();
36
37
//_dataBound = true;
38
}
39
40
private void DataBindToDataView(DataView oDataView)
41
{
42
this.LoadGrid(oDataView);
43
// Get some info about the dataset
44
}
45
46
private void DataBindToEnumerable(IEnumerable arList)
47
{
48
throw new NotSupportedException("该方法未被支持,后面的版本也许会支持");
49
}
50
51
private void LoadGrid(DataView oDataView)
52
{
53
DataTable oTable = oDataView.Table;
54
if (oTable == null || oTable.Rows.Count == 0) return;
55
BuildFromDataTable(oTable);
56
}
57
58
59
private void BuildFromDataTable(DataTable table)
60
{
61
if (this._measurefieldname == null || this._measurefieldname == "")
62
{
63
throw new ArgumentNullException("MeasureFieldName", "请设置数据列");
64
}
65
if ((this._onColumnsAxesFieldName == null || this._onColumnsAxesFieldName == "")
66
&& (this._onRowAxesFieldName == null || this._onRowAxesFieldName == "")
67
)
68
{
69
throw new ArgumentNullException("OnColumnsAxesFieldName OR OnRowAxesFieldName", "横轴和纵轴不能同时为空");
70
71
}
72
else
73
{
74
构建横竖轴#region 构建横竖轴
75
string[] cols = (this.OnColumnsAxesFieldName != null && this.OnColumnsAxesFieldName != "") ? this.OnColumnsAxesFieldName.Split(','): null;
76
string[] rows = (this.OnRowAxesFieldName != null && this.OnRowAxesFieldName != "") ? this.OnRowAxesFieldName.Split(',') : null;
77
string[] colsvalue =(this.OnColumnsAxesValueFieldName != null && this.OnColumnsAxesValueFieldName != "") ? this.OnColumnsAxesValueFieldName.Split(','): null;
78
string[] rowsvalue = (this.OnRowAxesValueFieldName != null && this.OnRowAxesValueFieldName != "") ? this.OnRowAxesValueFieldName.Split(',') : null;
79
if (colsvalue != null && colsvalue.Length != cols.Length)
80
{
81
throw new ArgumentNullException("OnColumnsAxesFieldName , OnColumnsAxesValueFieldName", "轴名称列和轴值列必须一一对应");
82
}
83
if (rowsvalue != null && rowsvalue.Length != rows.Length)
84
{
85
throw new ArgumentNullException("OnRowAxesFieldName , OnRowAxesValueFieldName", "轴名称列和轴值列必须一一对应");
86
}
87
88
// 声明需要用到的变量
89
PositionCollection pc;
90
Position ps;
91
MemberCollection mc;
92
Member mb;
93
int index ;
94
int valueindex =0;
95
DataRow[] arrdr;
96
string col;
97
string row;
98
string colvalue;
99
string rowvalue;
100
if (cols != null) //如果设置了维度列在竖轴上,则构建竖轴
101
{
102
pc = new PositionCollection();
103
for (int k = 0; k < cols.Length; k++ )
104
{
105
col = cols[k];
106
if (colsvalue != null)
107
{
108
colvalue = colsvalue[k];
109
valueindex = table.Columns[colvalue].Ordinal;
110
}
111
index = table.Columns[col].Ordinal;
112
ps = new Position();
113
ps.Name = col;
114
mc = new MemberCollection();
115
arrdr = table.Select("", col + " asc "); //过滤相同的维度信息做准备
116
for (int i = 0; i < arrdr.Length; i++)
117
{
118
if (arrdr[i][index].ToString() == "$#NULL#$") continue; // 过滤空的维度值
119
if (i == 0 || arrdr[i][index].ToString() != arrdr[i - 1][index].ToString())
120
{
121
mb = new Member();
122
mb.Caption = (arrdr[i][index] != null && arrdr[i][index] != System.DBNull.Value) ? arrdr[i][index].ToString() : "";
123
if (colsvalue != null)
124
{
125
mb.Value = (arrdr[i][valueindex] != null && arrdr[i][valueindex] != System.DBNull.Value) ? arrdr[i][valueindex].ToString() : "";
126
}
127
ps.Members.Add(mb);
128
}
129
}
130
if (this.ShowColumnsSum) //是否在竖轴上显示合计列
131
{
132
mb = new Member();
133
mb.Caption = this.SumText;
134
mb.IsSumTotal = true;
135
mb.Value = "$SUM$";
136
ps.Members.Add(mb);
137
}
138
this.ColumnsAxes.Add(ps);
139
}
140
141
142
}
143
if (rows != null) //构建横轴,同上
144
{
145
146
for (int k = 0; k < rows.Length; k++)
147
{
148
row = rows[k];
149
if (rowsvalue != null)//
150
{
151
rowvalue = rowsvalue[k];
152
valueindex = table.Columns[rowvalue].Ordinal;
153
}
154
index = table.Columns[row].Ordinal;
155
156
ps = new Position();
157
ps.Name = row;
158
mc = new MemberCollection();
159
arrdr = table.Select("", row+" asc ");
160
for (int i = 0; i < arrdr.Length ; i++)
161
{
162
if (arrdr[i][index].ToString() == "$#NULL#$") continue;
163
164
if (i == 0 || arrdr[i][index].ToString() != arrdr[i - 1][index].ToString())
165
{
166
mb = new Member();
167
mb.Caption = (arrdr[i][index] != null && arrdr[i][index] != System.DBNull.Value) ? arrdr[i][index].ToString() : "";
168
if (rowsvalue != null)
169
{
170
mb.Value = (arrdr[i][valueindex] != null && arrdr[i][valueindex] != System.DBNull.Value) ? arrdr[i][valueindex].ToString() : "";
171
}
172
ps.Members.Add(mb);
173
}
174
}
175
if (this.ShowRowsSum)
176
{
177
mb = new Member();
178
mb.Caption = this.SumText;
179
mb.IsSumTotal = true;
180
mb.Value = "$SUM$";
181
ps.Members.Add(mb);
182
}
183
this.RowAxes.Add(ps);
184
}
185
186
}
187
#endregion
188
189
获取数据#region 获取数据
190
//开始获取数据拉
191
int totalcols = 1;
192
foreach (Position cps in this.ColumnsAxes)
193
{
194
totalcols *= cps.Members.Count;
195
}
196
this.dataCells.BreakIndex = totalcols ;
197
int totalrows = 1;
198
foreach (Position rps in this.RowAxes)
199
{
200
totalrows *= rps.Members.Count;
201
}
202
203
int colscount = this.ColumnsAxes.Count;
204
int rowscount = this.RowAxes.Count;
205
string codition = "";
206
string fun = "";
207
208
int rowmindex = 0 ;
209
int colmindex = 0;
210
Cell cell;
211
for( int i =0 ;i<totalrows ; i++)
212
{
213
for (int j = 0; j < totalcols; j++)
214
{
215
codition = "";
216
fun = this._cellclientfunction;
217
for (int m = rowscount - 1; m >= 0; m--)
218
{
219
220
rowmindex = RowMemberIndex(m, i);
221
if (!this.RowAxes[m].Members[rowmindex].IsSumTotal)
222
{
223
if (codition != "") codition += " and ";
224
codition += this.RowAxes[m].Name + "='" + this.RowAxes[m].Members[rowmindex].Caption + "'";
225
}
226
if (fun != "")
227
{
228
fun = fun.Replace("{" + this.RowAxes[m].Name + "}", "'"+this.RowAxes[m].Members[rowmindex].Value.Replace("'","")+"'");
229
}
230
}
231
for (int n = colscount - 1; n >= 0; n--)
232
{
233
colmindex = ColMemberIndex(n, j);
234
if (!this.ColumnsAxes[n].Members[colmindex].IsSumTotal)
235
{
236
if (codition != "") codition += " and ";
237
codition += this.ColumnsAxes[n].Name + "='" + this.ColumnsAxes[n].Members[colmindex].Caption + "'";
238
}
239
if (fun != "")
240
{
241
fun = fun.Replace("{" + this.ColumnsAxes[n].Name + "}", "'" + this.ColumnsAxes[n].Members[colmindex].Value.Replace("'", "") + "'");
242
}
243
}
244
object o =table.Compute("sum(" + this.MeasureFieldName + ")", codition);
245
cell = new Cell();
246
if (this._cellclientfunction != null && this._cellclientfunction != "")
247
cell.ClientClickFunction = fun;
248
249
if (_formartstring != null && _formartstring != "")
250
cell.FormatString = _formartstring;
251
252
cell.Value = Convert.ToDecimal(o!=null && o !=System.DBNull.Value ?o:0);
253
this.dataCells.Add(cell);
254
fun = "";
255
}
256
}
257
#endregion
258
}
259
}
260
#endregion


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

绘制表格的部分


















































































































































































































































































其他一些辅助函数











































































































































































代码下载