TNB Library
TnbGrid.h
[詳解]
1#pragma once
13#include "TnbStrVector.h"
14
15
16
17//TNB Library
18namespace TNB
19{
20
21
22
32class CGrid
33{
34public:
35
38 {
44 };
45
48 {
50 ET_Date = 'D',
51 ET_Numeric = 'N',
53 ET_Logical = 'L',
54// ET_Memo = 'M', ///< メモ
55 };
56
59 {
61 size_t width;
62 size_t decimals;
65 TFieldInfo(LPCTSTR lpsz = NULL, size_t w = 0, size_t d = 0, EFieldType t = ET_Character)
66 : name(lpsz), width(w), decimals(d), type(t)
67 {
68 }
70 virtual void Deserialize (const IDeserializer& ds)
71 {
72 ds >> name >> width >> decimals >> type;
73 }
75 virtual void Serialize (ISerializer& _sr) const
76 {
77 _sr << name << width << decimals << type;
78 }
79 };
80
82 struct TDate
83 {
84 WORD year;
85 BYTE month;
86 BYTE day;
93 TDate(WORD y = 2000, BYTE m = 1, BYTE d = 1) : year(y), month(m), day(d)
94 {
95 }
100 int Get(void) const
101 {
102 return year * 10000 + month * 100 + day;
103 }
108 void Set(int i)
109 {
110 year = down_cast<WORD>(i / 10000);
111 month = down_cast<BYTE>((i / 100) % 100);
112 day = down_cast<BYTE>(i % 100);
113 }
114 };
115
116
117 //---------------------------
118
119
121 CGrid(void)
122 {
123 }
124
129 void AllDelete(void)
130 {
131 m_records.RemoveAll();
132 m_fields.RemoveAll();
133 }
134
139 size_t GetFieldCount(void) const
140 {
141 return m_fields.GetSize();
142 }
143
148 size_t GetRecordCount(void) const
149 {
150 return m_records.GetSize();
151 }
152
159 INDEX FindFieldName(LPCTSTR lpszFieldName) const
160 {
161 loop ( i, m_fields.GetSize() )
162 {
163 if ( m_fields[i].name.IsEqual(lpszFieldName) )
164 {
165 return i;
166 }
167 }
168 return INVALID_INDEX;
169 }
170
178 EFieldKind GetFieldInfo(TFieldInfo& _fi, INDEX field) const
179 {
180 if ( m_fields.IsInRange(field) )
181 {
182 _fi = m_fields[field];
183 return m_ToKind(_fi);
184 }
185 return EK_Invalid;
186 }
187
196 INDEX AddField(const TFieldInfo& fi)
197 {
198 if ( GetRecordCount() == 0 && ! fi.name.IsEmpty() && FindFieldName(fi.name) == INVALID_INDEX && fi.width >= 1 && fi.width <= 254 )
199 {
200 return m_fields.Add(fi);
201 }
202 return INVALID_INDEX;
203 }
204
214 INDEX AddCharacterField(LPCTSTR lpszFieldName, size_t width)
215 {
216 TFieldInfo fi(lpszFieldName, width, 0, ET_Character);
217 return AddField(fi);
218 }
219
231 INDEX AddNumericField(LPCTSTR lpszFieldName, size_t width, size_t dec = 0)
232 {
233 TFieldInfo fi(lpszFieldName, width, dec, ET_Numeric);
234 if ( width >= dec + 1 )
235 {
236 return AddField(fi);
237 }
238 return INVALID_INDEX;
239 }
240
252 INDEX AddFloatingField(LPCTSTR lpszFieldName, size_t width, size_t dec = 0)
253 {
254 TFieldInfo fi(lpszFieldName, width, dec, ET_Floating);
255 if ( width >= dec + 1 )
256 {
257 return AddField(fi);
258 }
259 return INVALID_INDEX;
260 }
261
270 INDEX AddDateField(LPCTSTR lpszFieldName)
271 {
272 TFieldInfo fi(lpszFieldName, 8, 0, ET_Date);
273 return AddField(fi);
274 }
275
283 bool DeleteField(INDEX field)
284 {
285 if ( GetRecordCount() == 0 )
286 {
287 return m_fields.Remove(field);
288 }
289 return false;
290 }
291
298 {
299 return m_records.RemoveAll();
300 }
301
308 INDEX AddRecord(void)
309 {
310 size_t len = GetFieldCount();
311 if ( len != 0 )
312 {
313 CDataVector dv;
314 dv.SetSize(len);
315 return m_records.Add(dv);
316 }
317 return INVALID_INDEX;
318 }
319
327 bool InsertRecord(INDEX record)
328 {
329 size_t len = GetFieldCount();
330 if ( len != 0 )
331 {
332 CDataVector dv;
333 dv.SetSize(len);
334 return m_records.Insert(record, dv);
335 }
336 return false;
337 }
338
345 bool DeleteRecord(INDEX record)
346 {
347 return m_records.Remove(record);
348 }
349
357 bool SetNullRecord(INDEX record, INDEX field)
358 {
359 TData* D = m_Ref(record, field);
360 if ( D != NULL )
361 {
362 D->SetString(_T(""));
363 return true;
364 }
365 return false;
366 }
367
377 bool SetStringRecord(INDEX record, INDEX field, LPCTSTR lpszString)
378 {
379 TData* D = m_Ref(record, field);
380 if ( D != NULL )
381 {
382 D->SetString(lpszString);
383 return true;
384 }
385 return false;
386 }
387
397 bool SetIntegerRecord(INDEX record, INDEX field, int value)
398 {
399 if ( m_ToKind(field) == EK_Integer )
400 {
401 TData* D = m_Ref(record, field);
402 if ( D != NULL )
403 {
404 D->SetFloat(value);
405 return true;
406 }
407 }
408 return false;
409 }
410
420 bool SetFloatRecord(INDEX record, INDEX field, double value)
421 {
422 if ( m_ToKind(field) == EK_Float )
423 {
424 TData* D = m_Ref(record, field);
425 if ( D != NULL )
426 {
427 D->SetFloat(value);
428 return true;
429 }
430 }
431 return false;
432 }
433
443 bool SetDateRecord(INDEX record, INDEX field, const TDate& date)
444 {
445 if ( m_ToKind(field) == EK_Date )
446 {
447 TData* D = m_Ref(record, field);
448 if ( D != NULL )
449 {
450 D->SetFloat(date.Get());
451 return true;
452 }
453 }
454 return false;
455 }
456
464 bool IsNullRecord(INDEX record, INDEX field) const
465 {
466 const TData* D = m_Ref(record, field);
467 if ( D != NULL )
468 {
469 return (D->hasString && D->string.IsEmpty());
470 }
471 return true;
472 }
473
481 CStr GetStringRecord(INDEX record, INDEX field, bool isAdjust = false) const
482 {
483 CStr str;
484 const TData* D = m_Ref(record, field);
485 if ( D != NULL )
486 {
487 const TFieldInfo& F = m_fields[field];
488 EFieldKind k = m_ToKind(F);
489 if ( D->hasString )
490 {
491 // データが文字列なのでそのまま
492 str = D->string;
493 }
494 else if ( k == EK_Float )
495 {
496 ASSERT( F.decimals > 0 );
497 if ( F.type == ET_Floating )
498 {
499 CStr f;
500 f.Format(_T("%%.%de"), F.decimals);
501 str.Format(f, D->value);
502 }
503 else if ( F.type == ET_Numeric )
504 {
505 CStr f;
506 f.Format(_T("%%.%df"), F.decimals);
507 str.Format(f, D->value);
508 }
509 else
510 {
511 ASSERTLIB( false );
512 }
513 }
514 else
515 {
516 int v = ToInt(D->value);
517 str.Format(_T("%d"), v);
518 }
519 if ( isAdjust )
520 {
521 size_t l = str.GetLength();
522 if ( l < F.width )
523 {
524 CStr sp = CStr::Lineup(' ', F.width - l);
525 if ( k == EK_String || k == EK_Date )
526 {
527 str += sp;
528 }
529 else
530 {
531 str = sp + str;
532 }
533 }
534 if ( str.GetLength() > F.width )
535 {
536 if ( k == EK_String || k == EK_Date )
537 {
538 str = str.Left(F.width);
539 }
540 else
541 {
542 str = str.Right(F.width);
543 }
544 }
545 }
546 }
547 return str;
548 }
549
556 int GetIntegerRecord(INDEX record, INDEX field) const
557 {
558 int r = 0;
559 const TData* D = m_Ref(record, field);
560 if ( D != NULL )
561 {
562 if ( D->hasString )
563 {
564 r = D->string.ToInt();
565 }
566 else
567 {
568 r = ToInt(D->value);
569 }
570 }
571 return r;
572 }
573
580 double GetFloatRecord(INDEX record, INDEX field) const
581 {
582 double r = 0;
583 const TData* D = m_Ref(record, field);
584 if ( D != NULL )
585 {
586 if ( D->hasString )
587 {
588 r = D->string.ToDouble();
589 }
590 else
591 {
592 r = D->value;
593 }
594 }
595 return r;
596 }
597
604 TDate GetDateRecord(INDEX record, INDEX field) const
605 {
606 TDate d;
607 d.Set(GetIntegerRecord(record, field));
608 return d;
609 }
610
611protected:
613 void Dump(void)
614 {
615 #ifdef _DEBUG
616 TFieldInfo fi;
617 size_t fc = GetFieldCount();
618 CWorkMemT<size_t> wd(fc);
619 // フィールド
620 TRACE0(" |");
621 loop ( i, fc )
622 {
623 GetFieldInfo(fi, i);
624 wd[i] = max(fi.name.GetLength(), fi.width);
625 TRACE1("%s", CStr::Fmt(CStr::Fmt(_T("%%-%ds|"), wd[i]), fi.name));
626 }
627 TRACE0("\n");
628 ::Sleep(10);
629 // フィールド(型)
630 TRACE0(" |");
631 loop ( i, fc )
632 {
633 GetFieldInfo(fi, i);
634 CStr s = CStr::Fmt(_T("%C,%d,%d"), fi.type, fi.width, fi.decimals);
635 TRACE1("%s", CStr::Fmt(CStr::Fmt(_T("%%-%ds|"), wd[i]), s));
636 }
637 TRACE0("\n");
638 ::Sleep(10);
639 // セパレータ
640 TRACE0("----+");
641 loop ( i, fc )
642 {
643 TRACE1("%s", CStr::Lineup('-', wd[i]) + "+");
644 }
645 TRACE0("\n");
646 ::Sleep(10);
647 // レコード
648 loop ( j, GetRecordCount() )
649 {
650 TRACE1("%4d|", j + 1);
651 loop ( i, fc )
652 {
653 TRACE1("%s", CStr::Fmt(CStr::Fmt(_T("%%-%ds|"), wd[i]), GetStringRecord(j, i, true)));
654 }
655 TRACE0("\n");
656 ::Sleep(10);
657 }
658 #endif // _DEBUG
659 }
660
661private:
663 EFieldKind m_ToKind(const TFieldInfo& info) const
664 {
665 switch ( info.type )
666 {
667 case ET_Character: // 文字列
668 case ET_Logical: // 論理(?,Y,N,T,F)
669// case ET_Memo: // メモ
670 return EK_String;
671 case ET_Date: // 年月日
672 return EK_Date;
673 case ET_Numeric: // 数値
674 case ET_Floating:
675 if ( info.decimals == 0 )
676 {
677 return EK_Integer;
678 }
679 return EK_Float;
680 default:
681 break;
682 }
683 return EK_String;
684// return EK_Invalid;
685 }
686 // フィールドインデックスから種類を
687 EFieldKind m_ToKind(INDEX field) const
688 {
689 if ( m_fields.IsInRange(field) )
690 {
691 return m_ToKind(m_fields[field]);
692 }
693 return EK_Invalid;
694 }
696 struct TData
697 {
698 bool hasString;
699 CStr string;
700 double value;
702 TData(void) : hasString(true)
703 {
704 }
706 void SetString(LPCTSTR lpsz)
707 {
708 hasString = true;
709 string = lpsz;
710 }
712 void SetFloat(double v)
713 {
714 hasString = false;
715 value = v;
716 }
717 virtual void Deserialize (const IDeserializer& ds)
718 {
719 ds >> hasString >> string >> value;
720 }
721 virtual void Serialize (ISerializer& _sr) const
722 {
723 _sr << hasString << string << value;
724 }
725 };
727 const TData* m_Ref(INDEX record, INDEX field) const
728 {
729 if ( m_fields.IsInRange(field) && m_records.IsInRange(record) )
730 {
731 const CDataVector& v = m_records[record];
732 ASSERT( v.IsInRange(field) );
733 return &v[field];
734 }
735 return NULL;
736 }
738 TData* m_Ref(INDEX record, INDEX field)
739 {
740 if ( m_fields.IsInRange(field) && m_records.IsInRange(record) )
741 {
742 CDataVector& v = m_records[record];
743 ASSERT( v.IsInRange(field) );
744 return &v[field];
745 }
746 return NULL;
747 }
748
749 CVectorT<TFieldInfo> m_fields;
750 typedef CVectorT<TData> CDataVector;
751 CVectorT<CDataVector> m_records;
752 friend class CGridTest;
753};
754
755
756
757}; // TNB
758
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
文字列情報配列管理関係のヘッダ
グリッド管理クラス.
Definition: TnbGrid.h:33
bool SetNullRecord(INDEX record, INDEX field)
[設定] レコードNULL設定.
Definition: TnbGrid.h:357
size_t GetFieldCount(void) const
[取得] フィールド数取得
Definition: TnbGrid.h:139
INDEX FindFieldName(LPCTSTR lpszFieldName) const
[検索] フィールド名検索
Definition: TnbGrid.h:159
void Dump(void)
Traceダンプ
Definition: TnbGrid.h:613
INDEX AddDateField(LPCTSTR lpszFieldName)
[追加] 日付フィールド追加.
Definition: TnbGrid.h:270
bool SetDateRecord(INDEX record, INDEX field, const TDate &date)
[設定] レコード日付設定.
Definition: TnbGrid.h:443
EFieldKind
フィールド種類
Definition: TnbGrid.h:38
@ EK_String
文字列
Definition: TnbGrid.h:39
@ EK_Integer
数値
Definition: TnbGrid.h:40
@ EK_Float
実数
Definition: TnbGrid.h:41
@ EK_Date
日付
Definition: TnbGrid.h:42
@ EK_Invalid
不正
Definition: TnbGrid.h:43
bool DeleteRecord(INDEX record)
[削除] レコード削除.
Definition: TnbGrid.h:345
bool AllDeleteRecord(void)
[削除] レコード全削除.
Definition: TnbGrid.h:297
bool SetStringRecord(INDEX record, INDEX field, LPCTSTR lpszString)
[設定] レコード文字列設定.
Definition: TnbGrid.h:377
CStr GetStringRecord(INDEX record, INDEX field, bool isAdjust=false) const
[取得] レコード文字列取得.
Definition: TnbGrid.h:481
INDEX AddCharacterField(LPCTSTR lpszFieldName, size_t width)
[追加] 文字フィールド追加.
Definition: TnbGrid.h:214
double GetFloatRecord(INDEX record, INDEX field) const
[取得] レコード実数取得.
Definition: TnbGrid.h:580
bool SetIntegerRecord(INDEX record, INDEX field, int value)
[設定] レコード数値設定.
Definition: TnbGrid.h:397
INDEX AddFloatingField(LPCTSTR lpszFieldName, size_t width, size_t dec=0)
[追加] 数値フィールド追加.
Definition: TnbGrid.h:252
bool InsertRecord(INDEX record)
[挿入] レコード挿入.
Definition: TnbGrid.h:327
EFieldType
フィールドタイプ
Definition: TnbGrid.h:48
@ ET_Numeric
数値
Definition: TnbGrid.h:51
@ ET_Logical
論理(?,Y,N,T,F)
Definition: TnbGrid.h:53
@ ET_Character
文字列
Definition: TnbGrid.h:49
@ ET_Date
年月日
Definition: TnbGrid.h:50
@ ET_Floating
浮動小数点数値
Definition: TnbGrid.h:52
EFieldKind GetFieldInfo(TFieldInfo &_fi, INDEX field) const
[取得] フィールド情報取得
Definition: TnbGrid.h:178
INDEX AddNumericField(LPCTSTR lpszFieldName, size_t width, size_t dec=0)
[追加] 数値フィールド追加.
Definition: TnbGrid.h:231
bool DeleteField(INDEX field)
[削除] フィールド削除.
Definition: TnbGrid.h:283
INDEX AddField(const TFieldInfo &fi)
[追加] フィールド追加.
Definition: TnbGrid.h:196
bool IsNullRecord(INDEX record, INDEX field) const
[確認] レコードNULL確認
Definition: TnbGrid.h:464
bool SetFloatRecord(INDEX record, INDEX field, double value)
[設定] レコード実数設定.
Definition: TnbGrid.h:420
TDate GetDateRecord(INDEX record, INDEX field) const
[取得] レコード日付取得.
Definition: TnbGrid.h:604
CGrid(void)
コンストラクタ
Definition: TnbGrid.h:121
void AllDelete(void)
[削除] 全削除.
Definition: TnbGrid.h:129
INDEX AddRecord(void)
[追加] レコード追加.
Definition: TnbGrid.h:308
size_t GetRecordCount(void) const
[取得] レコード数取得
Definition: TnbGrid.h:148
int GetIntegerRecord(INDEX record, INDEX field) const
[取得] レコード数値取得.
Definition: TnbGrid.h:556
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
CStrT Left(size_t iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:801
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
CStrT Right(INT_PTR iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:811
static CStrT Fmt(const TCHAR *lpszFormat,...)
[作成] 書式付き文字列作成
Definition: TnbStr.h:1206
void Format(const TYP *lpszFormat,...)
[代入] 書式付き文字列代入.
Definition: TnbStr.h:359
static CStrT Lineup(TCHAR t, size_t length)
[作成] 指定文字を並べた文字列作成
Definition: TnbStr.h:1222
配列型情報管理テンプレート
Definition: TnbVector.h:75
virtual bool SetSize(size_t size)
[操作] サイズ指定
Definition: TnbVector.h:618
ワークメモリテンプレート.
Definition: TnbDef.h:633
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
TNB Library
Definition: TnbDoxyTitle.txt:2
日付情報
Definition: TnbGrid.h:83
WORD year
Definition: TnbGrid.h:84
BYTE month
Definition: TnbGrid.h:85
void Set(int i)
[設定] INT型設定
Definition: TnbGrid.h:108
TDate(WORD y=2000, BYTE m=1, BYTE d=1)
コンストラクタ
Definition: TnbGrid.h:93
BYTE day
Definition: TnbGrid.h:86
int Get(void) const
[取得] INT型取得
Definition: TnbGrid.h:100
フィールド情報
Definition: TnbGrid.h:59
virtual void Deserialize(const IDeserializer &ds)
デシリアライズ
Definition: TnbGrid.h:70
TFieldInfo(LPCTSTR lpsz=NULL, size_t w=0, size_t d=0, EFieldType t=ET_Character)
コンストラクタ
Definition: TnbGrid.h:65
EFieldType type
タイプ
Definition: TnbGrid.h:63
virtual void Serialize(ISerializer &_sr) const
シリアライズ
Definition: TnbGrid.h:75
size_t decimals
小数点部幅
Definition: TnbGrid.h:62
CStr name
名前
Definition: TnbGrid.h:60
デシリアライザーインターフェースクラス.
シリアライザーインターフェースクラス.