class//COmdFileFactor

在此,我們使用了Design Pattern的工廠模式,讓每一個omd細節以繼承的方式讓它們可以做「動態連結」在主程式裡的code就只要修改new的部份。
此外,還要實作類似Excel的儲存格存取動作,提供每一個繼承這個類別使用。

COmdFileFactor.h

// OmdFile1.h: interface for the COmdFile class.
//
//////////////////////////////////////////////////////////////////////

#ifndef OMDFILEPTR_H
#define OMDFILEPTR_H

#include "TxtFile.h"
#include "RNA.h"
#include <vector>
#include <iterator>
#include "OmdHead.h"

class COmdFileFactor
{
//Diff of Txt file
protected:
    OmdHead m_omdFileHead;

public:
    OmdHead& GetFileHead(){ return m_omdFileHead; };
    const OmdHead& GetFileHead() const{ return m_omdFileHead; };
    void SetFileHead(const OmdHead& _H){ m_omdFileHead = _H; };

protected:
//    virtual BOOL isOldForm(TxtStrData&) = 0;
    const CString GetLine(const int& ) const;    
    const CString GetCell(const int&, const int& ) const;
    const CString GetCell(const TCHAR& , const int& ) const;   // 0< c<=24
    const CString GetCell(const PTCHAR& , const int& ) const;  //25<=c,從AA開始算

protected:
    TxtStrData m_dTxt;
//the same of Txt file;
    CTxtFile   m_fTxt;
    RNA m_dOmd;

public:
    COmdFileFactor();
    virtual ~COmdFileFactor();
    BOOL Open(LPCTSTR, CFileException&);
    BOOL Save(LPCTSTR, CFileException&);

    void Close(){ m_fTxt.Close(); };

    RNA  oOmdData()         { txt2omd(); return m_dOmd; };
    void oOmdData(RNA& data){ txt2omd(); data = m_dOmd; };
    void iOmdData(const RNA& data){ m_dOmd = data; omd2txt(); };

private:
     virtual void txt2omd() = 0;
     virtual void omd2txt() = 0;
     void ErrorMsg(CFileException& ) const;
};

#endif // OMDFILE0_H

COmdFileFactor.cpp

讓讀寫介面與行為,類似TxtFile

讓txtfile的介面和omdfile的介面相同,因為讀寫的概念是相同的,在此優先保有整體概念性,並且讓程式碼的實作也類似Txt File
BOOL COmdFileFactor::Open(LPCTSTR path, CFileException& fx)
{
    if (m_fTxt.Open(path, fx))
        return TRUE;
    else
    {
        ErrorMsg(fx);
        return FALSE;
    }
}

BOOL COmdFileFactor::Save(LPCTSTR path, CFileException& fx)
{
    if (m_fTxt.Save(path, fx))
    {
        return TRUE;
    }
    else
    {
        ErrorMsg(fx);
        m_fTxt.Close();
        return FALSE;
    }
}

純文字的「類Excel」操作介面實作

在此是以tab鍵做分割,讓純文字檔有類似Excel的架構,Excel本身還有一個.csv格式就是這樣,這樣做可以大幅度增加程式的可讀性,隱藏複雜度。
而且,也將ABC的介面實作進來,並且支援Excel超過Z之後操作的介面。
之後就可以像Excel用A3、AB2這樣定儲存格座標。
const CString COmdFileFactor::GetLine(const int& lineIndex) const//OK
{
    if (lineIndex <= 0)
        return "出現錯誤: 參數 < 1";
    else if (lineIndex > m_dTxt.size())
        return "超出範圍";
    else
        return m_dTxt.at((std::vector<CString>::size_type)lineIndex - 1);
}

const CString COmdFileFactor::GetCell(const int& Word, const int& line) const
{
    CString strBuf1;
    CString strBuf2;
    
    strBuf1 = GetLine(line) + '\t';   
    
    if (!strBuf1.IsEmpty())
    {
        int wBegin = 0, wLength = 0;
        
        for (int i = 0; i < Word; ++i)
        {
            wLength = strBuf1.Right(strBuf1.GetLength() - wBegin).Find('\t');
            strBuf2.Format("%s", strBuf1.Mid(wBegin, wLength));
            wBegin += wLength + 1;
        }
    }
    if (strBuf2.IsEmpty())
        strBuf2.Format("");//(內容空白)
    return strBuf2;
}

const CString COmdFileFactor::GetCell(const TCHAR& c, const int& n) const
{
    int x;
    x = c - 'A'+1;
    return GetCell(x, n);
}

const CString COmdFileFactor::GetCell(const PTCHAR& c, const int& n) const
{
    CString str;
    str.Format("%s", c);
    
    TCHAR c1;
    TCHAR c2;
    c1 = *(str.Left(1).GetBuffer(str.Left(1).GetLength()));
    c2 = *(str.Right(1).GetBuffer(str.Left(1).GetLength()));
    
    int x;
    x = (c1 - 'A'+1) + (c2 - 'A'+1) + 'Z'+1;//+25是因為這個部份是從AA開始算,所以要跳過A~Z
        
    return GetCell(x, n);
}

沒有留言:

張貼留言

文章分類維度