转自风满袖的Blog http://jiezhi.cnblogs.com/archive/2005/01/05/86838.html
1
using
System;
2
using
System.Collections;
3
using
System.Data;
4
5
namespace
Common
6
{
7
/**//**//**//// <summary>
8
/// DataSet助手
9
/// </summary>
10
public class DataSetHelper
11
{
12
private class FieldInfo
13
{
14
public string RelationName;
15
public string FieldName;
16
public string FieldAlias;
17
public string Aggregate;
18
}
19
20
private DataSet ds;
21
private ArrayList m_FieldInfo;
22
private string m_FieldList;
23
private ArrayList GroupByFieldInfo;
24
private string GroupByFieldList;
25
26
public DataSet DataSet
27
{
28
get
{ return ds; }
29
}
30
31
构造方法#region 构造方法
32
33
public DataSetHelper()
34
{
35
ds = null;
36
}
37
38
public DataSetHelper(ref DataSet dataSet)
39
{
40
ds = dataSet;
41
}
42
43
#endregion
44
45
私有方法#region 私有方法
46
47
/**//// <summary>
48
/// 比较两列
49
/// </summary>
50
/// <param name="objectA"></param>
51
/// <param name="objectB"></param>
52
/// <returns></returns>
53
private bool ColumnEqual(object objectA, object objectB)
54
{
55
if ( objectA == DBNull.Value && objectB == DBNull.Value )
56
{
57
return true;
58
}
59
if ( objectA == DBNull.Value || objectB == DBNull.Value )
60
{
61
return false;
62
}
63
return ( objectA.Equals( objectB ) );
64
}
65
66
/**//// <summary>
67
/// 比较两行
68
/// </summary>
69
/// <param name="rowA">A表的行</param>
70
/// <param name="rowB">B表的行</param>
71
/// <param name="columns">所对应的列</param>
72
/// <returns></returns>
73
private bool RowEqual(DataRow rowA, DataRow rowB, DataColumnCollection columns)
74
{
75
bool result = true;
76
for ( int i = 0; i < columns.Count; i++ )
77
{
78
result &= ColumnEqual( rowA[ columns[ i ].ColumnName ], rowB[ columns[ i ].ColumnName ] );
79
}
80
return result;
81
}
82
83
/**//// <summary>
84
/// 暂时不知道
85
/// </summary>
86
/// <param name="fieldList"></param>
87
/// <param name="allowRelation"></param>
88
private void ParseFieldList(string fieldList, bool allowRelation)
89
{
90
if ( m_FieldList == fieldList )
91
{
92
return;
93
}
94
m_FieldInfo = new ArrayList();
95
m_FieldList = fieldList;
96
FieldInfo Field;
97
string[] FieldParts;
98
string[] Fields = fieldList.Split( ',' );
99
for ( int i = 0; i <= Fields.Length - 1; i++ )
100
{
101
Field = new FieldInfo();
102
FieldParts = Fields[ i ].Trim().Split( ' ' );
103
switch ( FieldParts.Length )
104
{
105
case 1:
106
//to be set at the end of the loop
107
break;
108
case 2:
109
Field.FieldAlias = FieldParts[ 1 ];
110
break;
111
default:
112
return;
113
}
114
FieldParts = FieldParts[ 0 ].Split( '.' );
115
switch ( FieldParts.Length )
116
{
117
case 1:
118
Field.FieldName = FieldParts[ 0 ];
119
break;
120
case 2:
121
if ( allowRelation == false )
122
{
123
return;
124
}
125
Field.RelationName = FieldParts[ 0 ].Trim();
126
Field.FieldName = FieldParts[ 1 ].Trim();
127
break;
128
default:
129
return;
130
}
131
if ( Field.FieldAlias == null )
132
{
133
Field.FieldAlias = Field.FieldName;
134
}
135
m_FieldInfo.Add( Field );
136
}
137
}
138
139
/**//// <summary>
140
/// 创建DataTable
141
/// </summary>
142
/// <param name="tableName">表名</param>
143
/// <param name="sourceTable">源表</param>
144
/// <param name="fieldList"></param>
145
/// <returns></returns>
146
private DataTable CreateTable(string tableName, DataTable sourceTable, string fieldList)
147
{
148
DataTable dt;
149
if ( fieldList.Trim() == "" )
150
{
151
dt = sourceTable.Clone();
152
dt.TableName = tableName;
153
}
154
else
155
{
156
dt = new DataTable( tableName );
157
ParseFieldList( fieldList, false );
158
DataColumn dc;
159
foreach ( FieldInfo Field in m_FieldInfo )
160
{
161
dc = sourceTable.Columns[ Field.FieldName ];
162
DataColumn column = new DataColumn();
163
column.ColumnName = Field.FieldAlias;
164
column.DataType = dc.DataType;
165
column.MaxLength = dc.MaxLength;
166
column.Expression = dc.Expression;
167
dt.Columns.Add( column );
168
}
169
}
170
if ( ds != null )
171
{
172
ds.Tables.Add( dt );
173
}
174
return dt;
175
}
176
177
/**//// <summary>
178
/// 插入表
179
/// </summary>
180
/// <param name="destTable">DataTable</param>
181
/// <param name="sourceTable">源DataTable</param>
182
/// <param name="fieldList"></param>
183
/// <param name="rowFilter"></param>
184
/// <param name="sort"></param>
185
private void InsertInto(DataTable destTable, DataTable sourceTable,
186
string fieldList, string rowFilter, string sort)
187
{
188
ParseFieldList( fieldList, false );
189
DataRow[] rows = sourceTable.Select( rowFilter, sort );
190
DataRow destRow;
191
foreach ( DataRow sourceRow in rows )
192
{
193
destRow = destTable.NewRow();
194
if ( fieldList == "" )
195
{
196
foreach ( DataColumn dc in destRow.Table.Columns )
197
{
198
if ( dc.Expression == "" )
199
{
200
destRow[ dc ] = sourceRow[ dc.ColumnName ];
201
}
202
}
203
}
204
else
205
{
206
foreach ( FieldInfo field in m_FieldInfo )
207
{
208
destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
209
}
210
}
211
destTable.Rows.Add( destRow );
212
}
213
}
214
215
/**//// <summary>
216
/// 暂时不知道
217
/// </summary>
218
/// <param name="FieldList"></param>
219
private void ParseGroupByFieldList(string FieldList)
220
{
221
if ( GroupByFieldList == FieldList )
222
{
223
return;
224
}
225
GroupByFieldInfo = new ArrayList();
226
FieldInfo Field;
227
string[] FieldParts;
228
string[] Fields = FieldList.Split( ',' );
229
for ( int i = 0; i <= Fields.Length - 1; i++ )
230
{
231
Field = new FieldInfo();
232
FieldParts = Fields[ i ].Trim().Split( ' ' );
233
switch ( FieldParts.Length )
234
{
235
case 1:
236
//to be set at the end of the loop
237
break;
238
case 2:
239
Field.FieldAlias = FieldParts[ 1 ];
240
break;
241
default:
242
return;
243
}
244
245
FieldParts = FieldParts[ 0 ].Split( '(' );
246
switch ( FieldParts.Length )
247
{
248
case 1:
249
Field.FieldName = FieldParts[ 0 ];
250
break;
251
case 2:
252
Field.Aggregate = FieldParts[ 0 ].Trim().ToLower();
253
Field.FieldName = FieldParts[ 1 ].Trim( ' ', ')' );
254
break;
255
default:
256
return;
257
}
258
if ( Field.FieldAlias == null )
259
{
260
if ( Field.Aggregate == null )
261
{
262
Field.FieldAlias = Field.FieldName;
263
}
264
else
265
{
266
Field.FieldAlias = Field.Aggregate + "of" + Field.FieldName;
267
}
268
}
269
GroupByFieldInfo.Add( Field );
270
}
271
GroupByFieldList = FieldList;
272
}
273
274
/**//// <summary>
275
/// 创建一个分组DataTable
276
/// </summary>
277
/// <param name="tableName">表名</param>
278
/// <param name="sourceTable">DataTable</param>
279
/// <param name="fieldList">分组字段</param>
280
/// <returns></returns>
281
private DataTable CreateGroupByTable(string tableName, DataTable sourceTable, string fieldList)
282
{
283
if ( fieldList == null || fieldList.Length == 0 )
284
{
285
return sourceTable.Clone();
286
}
287
else
288
{
289
DataTable dt = new DataTable( tableName );
290
ParseGroupByFieldList( fieldList );
291
foreach ( FieldInfo Field in GroupByFieldInfo )
292
{
293
DataColumn dc = sourceTable.Columns[ Field.FieldName ];
294
if ( Field.Aggregate == null )
295
{
296
dt.Columns.Add( Field.FieldAlias, dc.DataType, dc.Expression );
297
}
298
else
299
{
300
dt.Columns.Add( Field.FieldAlias, dc.DataType );
301
}
302
}
303
if ( ds != null )
304
{
305
ds.Tables.Add( dt );
306
}
307
return dt;
308
}
309
}
310
311
private void InsertGroupByInto(DataTable destTable, DataTable sourceTable, string fieldList,
312
string rowFilter, string groupBy)
313
{
314
if ( fieldList == null || fieldList.Length == 0 )
315
{
316
return;
317
}
318
ParseGroupByFieldList( fieldList );
319
ParseFieldList( groupBy, false );
320
DataRow[] rows = sourceTable.Select( rowFilter, groupBy );
321
DataRow lastSourceRow = null, destRow = null;
322
bool sameRow;
323
int rowCount = 0;
324
foreach ( DataRow sourceRow in rows )
325
{
326
sameRow = false;
327
if ( lastSourceRow != null )
328
{
329
sameRow = true;
330
foreach ( FieldInfo Field in m_FieldInfo )
331
{
332
if ( !ColumnEqual( lastSourceRow[ Field.FieldName ], sourceRow[ Field.FieldName ] ) )
333
{
334
sameRow = false;
335
break;
336
}
337
}
338
if ( !sameRow )
339
{
340
destTable.Rows.Add( destRow );
341
}
342
}
343
if ( !sameRow )
344
{
345
destRow = destTable.NewRow();
346
rowCount = 0;
347
}
348
rowCount += 1;
349
foreach ( FieldInfo field in GroupByFieldInfo )
350
{
351
switch ( field.Aggregate.ToLower() )
352
{
353
case null:
354
case "":
355
case "last":
356
destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
357
break;
358
case "first":
359
if ( rowCount == 1 )
360
{
361
destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
362
}
363
break;
364
case "count":
365
destRow[ field.FieldAlias ] = rowCount;
366
break;
367
case "sum":
368
destRow[ field.FieldAlias ] = Add( destRow[ field.FieldAlias ], sourceRow[ field.FieldName ] );
369
break;
370
case "max":
371
destRow[ field.FieldAlias ] = Max( destRow[ field.FieldAlias ], sourceRow[ field.FieldName ] );
372
break;
373
case "min":
374
if ( rowCount == 1 )
375
{
376
destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
377
}
378
else
379
{
380
destRow[ field.FieldAlias ] = Min( destRow[ field.FieldAlias ], sourceRow[ field.FieldName ] );
381
}
382
break;
383
}
384
}
385
lastSourceRow = sourceRow;
386
}
387
if ( destRow != null )
388
{
389
destTable.Rows.Add( destRow );
390
}
391
}
392
393
private object Min(object a, object b)
394
{
395
if ( ( a is DBNull ) || ( b is DBNull ) )
396
{
397
return DBNull.Value;
398
}
399
if ( ( (IComparable) a ).CompareTo( b ) == -1 )
400
{
401
return a;
402
}
403
else
404
{
405
return b;
406
}
407
}
408
409
private object Max(object a, object b)
410
{
411
if ( a is DBNull )
412
{
413
return b;
414
}
415
if ( b is DBNull )
416
{
417
return a;
418
}
419
if ( ( (IComparable) a ).CompareTo( b ) == 1 )
420
{
421
return a;
422
}
423
else
424
{
425
return b;
426
}
427
}
428
429
private object Add(object a, object b)
430
{
431
if ( a is DBNull )
432
{
433
return b;
434
}
435
if ( b is DBNull )
436
{
437
return a;
438
}
439
return ( (decimal) a + (decimal) b );
440
}
441
442
private DataTable CreateJoinTable(string tableName, DataTable sourceTable, string fieldList)
443
{
444
if ( fieldList == null )
445
{
446
return sourceTable.Clone();
447
}
448
else
449
{
450
DataTable dt = new DataTable( tableName );
451
ParseFieldList( fieldList, true );
452
foreach ( FieldInfo field in m_FieldInfo )
453
{
454
if ( field.RelationName == null )
455
{
456
DataColumn dc = sourceTable.Columns[ field.FieldName ];
457
dt.Columns.Add( dc.ColumnName, dc.DataType, dc.Expression );
458
}
459
else
460
{
461
DataColumn dc = sourceTable.ParentRelations[ field.RelationName ].ParentTable.Columns[ field.FieldName ];
462
dt.Columns.Add( dc.ColumnName, dc.DataType, dc.Expression );
463
}
464
}
465
if ( ds != null )
466
{
467
ds.Tables.Add( dt );
468
}
469
return dt;
470
}
471
}
472
473
private void InsertJoinInto(DataTable destTable, DataTable sourceTable,
474
string fieldList, string rowFilter, string sort)
475
{
476
if ( fieldList == null )
477
{
478
return;
479
}
480
else
481
{
482
ParseFieldList( fieldList, true );
483
DataRow[] Rows = sourceTable.Select( rowFilter, sort );
484
foreach ( DataRow SourceRow in Rows )
485
{
486
DataRow DestRow = destTable.NewRow();
487
foreach ( FieldInfo Field in m_FieldInfo )
488
{
489
if ( Field.RelationName == null )
490
{
491
DestRow[ Field.FieldName ] = SourceRow[ Field.FieldName ];
492
}
493
else
494
{
495
DataRow ParentRow = SourceRow.GetParentRow( Field.RelationName );
496
DestRow[ Field.FieldName ] = ParentRow[ Field.FieldName ];
497
}
498
}
499
destTable.Rows.Add( DestRow );
500
}
501
}
502
}
503
504
#endregion
505
506
SelectDistinct / Distinct#region SelectDistinct / Distinct
507
508
/**//**//**//// <summary>
509
/// 按照fieldName从sourceTable中选择出不重复的行,
510
/// 相当于select distinct fieldName from sourceTable
511
/// </summary>
512
/// <param name="tableName">表名</param>
513
/// <param name="sourceTable">源DataTable</param>
514
/// <param name="fieldName">列名</param>
515
/// <returns>一个新的不含重复行的DataTable,列只包括fieldName指明的列</returns>
516
public DataTable SelectDistinct(string tableName, DataTable sourceTable, string fieldName)
517
{
518
DataTable dt = new DataTable( tableName );
519
dt.Columns.Add( fieldName, sourceTable.Columns[ fieldName ].DataType );
520
521
object lastValue = null;
522
foreach ( DataRow dr in sourceTable.Select( "", fieldName ) )
523
{
524
if ( lastValue == null || !( ColumnEqual( lastValue, dr[ fieldName ] ) ) )
525
{
526
lastValue = dr[ fieldName ];
527
dt.Rows.Add( new object[]
{lastValue} );
528
}
529
}
530
if ( ds != null && !ds.Tables.Contains( tableName ) )
531
{
532
ds.Tables.Add( dt );
533
}
534
return dt;
535
}
536
537
/**//**//**//// <summary>
538
/// 按照fieldName从sourceTable中选择出不重复的行,
539
/// 相当于select distinct fieldName1,fieldName2,,fieldNamen from sourceTable
540
/// </summary>
541
/// <param name="tableName">表名</param>
542
/// <param name="sourceTable">源DataTable</param>
543
/// <param name="fieldNames">列名数组</param>
544
/// <returns>一个新的不含重复行的DataTable,列只包括fieldNames中指明的列</returns>
545
public DataTable SelectDistinct(string tableName, DataTable sourceTable, string[] fieldNames)
546
{
547
DataTable dt = new DataTable( tableName );
548
object[] values = new object[fieldNames.Length];
549
string fields = "";
550
for ( int i = 0; i < fieldNames.Length; i++ )
551
{
552
dt.Columns.Add( fieldNames[ i ], sourceTable.Columns[ fieldNames[ i ] ].DataType );
553
fields += fieldNames[ i ] + ",";
554
}
555
fields = fields.Remove( fields.Length - 1, 1 );
556
DataRow lastRow = null;
557
foreach ( DataRow dr in sourceTable.Select( "", fields ) )
558
{
559
if ( lastRow == null || !( RowEqual( lastRow, dr, dt.Columns ) ) )
560
{
561
lastRow = dr;
562
for ( int i = 0; i < fieldNames.Length; i++ )
563
{
564
values[ i ] = dr[ fieldNames[ i ] ];
565
}
566
dt.Rows.Add( values );
567
}
568
}
569
if ( ds != null && !ds.Tables.Contains( tableName ) )
570
{
571
ds.Tables.Add( dt );
572
}
573
return dt;
574
}
575
576
/**//**//**//// <summary>
577
/// 按照fieldName从sourceTable中选择出不重复的行,
578
/// 并且包含sourceTable中所有的列。
579
/// </summary>
580
/// <param name="tableName">表名</param>
581
/// <param name="sourceTable">源表</param>
582
/// <param name="fieldName">字段</param>
583
/// <returns>一个新的不含重复行的DataTable</returns>
584
public DataTable Distinct(string tableName, DataTable sourceTable, string fieldName)
585
{
586
DataTable dt = sourceTable.Clone();
587
dt.TableName = tableName;
588
589
object lastValue = null;
590
foreach ( DataRow dr in sourceTable.Select( "", fieldName ) )
591
{
592
if ( lastValue == null || !( ColumnEqual( lastValue, dr[ fieldName ] ) ) )
593
{
594
lastValue = dr[ fieldName ];
595
dt.Rows.Add( dr.ItemArray );
596
}
597
}
598
if ( ds != null && !ds.Tables.Contains( tableName ) )
599
{
600
ds.Tables.Add( dt );
601
}
602
return dt;
603
}
604
605
/**//**//**//// <summary>
606
/// 按照fieldNames从sourceTable中选择出不重复的行,
607
/// 并且包含sourceTable中所有的列。
608
/// </summary>
609
/// <param name="tableName">表名</param>
610
/// <param name="sourceTable">源表</param>
611
/// <param name="fieldNames">字段</param>
612
/// <returns>一个新的不含重复行的DataTable</returns>
613
public DataTable Distinct(string tableName, DataTable sourceTable, string[] fieldNames)
614
{
615
DataTable dt = sourceTable.Clone();
616
dt.TableName = tableName;
617
string fields = "";
618
for ( int i = 0; i < fieldNames.Length; i++ )
619
{
620
fields += fieldNames[ i ] + ",";
621
}
622
fields = fields.Remove( fields.Length - 1, 1 );
623
DataRow lastRow = null;
624
foreach ( DataRow dr in sourceTable.Select( "", fields ) )
625
{
626
if ( lastRow == null || !( RowEqual( lastRow, dr, dt.Columns ) ) )
627
{
628
lastRow = dr;
629
dt.Rows.Add( dr.ItemArray );
630
}
631
}
632
if ( ds != null && !ds.Tables.Contains( tableName ) )
633
{
634
ds.Tables.Add( dt );
635
}
636
return dt;
637
}
638
639
#endregion
640
641
Select Table Into#region Select Table Into
642
643
/**//**//**//// <summary>
644
/// 按sort排序,按rowFilter过滤sourceTable,
645
/// 复制fieldList中指明的字段的数据到新DataTable,并返回之
646
/// </summary>
647
/// <param name="tableName">表名</param>
648
/// <param name="sourceTable">源表</param>
649
/// <param name="fieldList">字段列表</param>
650
/// <param name="rowFilter">过滤条件</param>
651
/// <param name="sort">排序</param>
652
/// <returns>新DataTable</returns>
653
public DataTable SelectInto(string tableName, DataTable sourceTable,
654
string fieldList, string rowFilter, string sort)
655
{
656
DataTable dt = CreateTable( tableName, sourceTable, fieldList );
657
InsertInto( dt, sourceTable, fieldList, rowFilter, sort );
658
return dt;
659
}
660
661
#endregion
662
663
Group By Table#region Group By Table
664
665
public DataTable SelectGroupByInto(string tableName, DataTable sourceTable, string fieldList,
666
string rowFilter, string groupBy)
667
{
668
DataTable dt = CreateGroupByTable( tableName, sourceTable, fieldList );
669
InsertGroupByInto( dt, sourceTable, fieldList, rowFilter, groupBy );
670
return dt;
671
}
672
673
#endregion
674
675
Join Tables#region Join Tables
676
677
public DataTable SelectJoinInto(string tableName, DataTable sourceTable, string fieldList, string rowFilter, string sort)
678
{
679
DataTable dt = CreateJoinTable( tableName, sourceTable, fieldList );
680
InsertJoinInto( dt, sourceTable, fieldList, rowFilter, sort );
681
return dt;
682
}
683
684
#endregion
685
686
Create Table#region Create Table
687
688
public DataTable CreateTable(string tableName, string fieldList)
689
{
690
DataTable dt = new DataTable( tableName );
691
DataColumn dc;
692
string[] Fields = fieldList.Split( ',' );
693
string[] FieldsParts;
694
string Expression;
695
foreach ( string Field in Fields )
696
{
697
FieldsParts = Field.Trim().Split( " ".ToCharArray(), 3 ); // allow for spaces in the expression
698
// add fieldname and datatype
699
if ( FieldsParts.Length == 2 )
700
{
701
dc = dt.Columns.Add( FieldsParts[ 0 ].Trim(), Type.GetType( "System." + FieldsParts[ 1 ].Trim(), true, true ) );
702
dc.AllowDBNull = true;
703
}
704
else if ( FieldsParts.Length == 3 ) // add fieldname, datatype, and expression
705
{
706
Expression = FieldsParts[ 2 ].Trim();
707
if ( Expression.ToUpper() == "REQUIRED" )
708
{
709
dc = dt.Columns.Add( FieldsParts[ 0 ].Trim(), Type.GetType( "System." + FieldsParts[ 1 ].Trim(), true, true ) );
710
dc.AllowDBNull = false;
711
}
712
else
713
{
714
dc = dt.Columns.Add( FieldsParts[ 0 ].Trim(), Type.GetType( "System." + FieldsParts[ 1 ].Trim(), true, true ), Expression );
715
}
716
}
717
else
718
{
719
return null;
720
}
721
}
722
if ( ds != null )
723
{
724
ds.Tables.Add( dt );
725
}
726
return dt;
727
}
728
729
public DataTable CreateTable(string tableName, string fieldList, string keyFieldList)
730
{
731
DataTable dt = CreateTable( tableName, fieldList );
732
string[] KeyFields = keyFieldList.Split( ',' );
733
if ( KeyFields.Length > 0 )
734
{
735
DataColumn[] KeyFieldColumns = new DataColumn[KeyFields.Length];
736
int i;
737
for ( i = 1; i == KeyFields.Length - 1; ++i )
738
{
739
KeyFieldColumns[ i ] = dt.Columns[ KeyFields[ i ].Trim() ];
740
}
741
dt.PrimaryKey = KeyFieldColumns;
742
}
743
return dt;
744
}
745
746
#endregion
747
}
748
}
749

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

279

280

281

282



283

284



285

286

287

288



289

290

291

292



293

294

295



296

297

298

299



300

301

302

303

304



305

306

307

308

309

310

311

312

313



314

315



316

317

318

319

320

321

322

323

324

325



326

327

328



329

330

331



332

333



334

335

336

337

338

339



340

341

342

343

344



345

346

347

348

349

350



351

352



353

354

355

356

357

358

359

360



361

362

363

364

365

366

367

368

369

370

371

372

373

374

375



376

377

378

379



380

381

382

383

384

385

386

387

388



389

390

391

392

393

394



395

396



397

398

399

400



401

402

403

404



405

406

407

408

409

410



411

412



413

414

415

416



417

418

419

420



421

422

423

424



425

426

427

428

429

430



431

432



433

434

435

436



437

438

439

440

441

442

443



444

445



446

447

448

449



450

451

452

453



454

455



456

457

458

459

460



461

462

463

464

465

466



467

468

469

470

471

472

473

474

475



476

477



478

479

480

481



482

483

484

485



486

487

488



489

490



491

492

493

494



495

496

497

498

499

500

501

502

503

504

505

506


507

508


509

510

511

512

513

514

515

516

517



518

519

520

521

522

523



524

525



526

527



528

529

530

531



532

533

534

535

536

537


538

539

540

541

542

543

544

545

546



547

548

549

550

551



552

553

554

555

556

557

558



559

560



561

562

563



564

565

566

567

568

569

570



571

572

573

574

575

576


577

578

579

580

581

582

583

584

585



586

587

588

589

590

591



592

593



594

595

596

597

598

599



600

601

602

603

604

605


606

607

608

609

610

611

612

613

614



615

616

617

618

619



620

621

622

623

624

625



626

627



628

629

630

631

632

633



634

635

636

637

638

639

640

641


642

643


644

645

646

647

648

649

650

651

652

653

654

655



656

657

658

659

660

661

662

663


664

665

666

667



668

669

670

671

672

673

674

675


676

677

678



679

680

681

682

683

684

685

686


687

688

689



690

691

692

693

694

695

696



697

698

699

700



701

702

703

704

705



706

707

708



709

710

711

712

713



714

715

716

717

718



719

720

721

722

723



724

725

726

727

728

729

730



731

732

733

734



735

736

737

738



739

740

741

742

743

744

745

746

747

748

749
