2018年10月1日 星期一

網頁開發(4) JQuery Datepicker 日期選擇器

這次要記錄的是 JQuery 中的 Datepicker
其實 DatepickerJQuery UI 裡的一個部件

以下連結可以載 JQuery UI

載完後就 Link 到自己的檔案裡就可以使用
    <link rel="stylesheet" type="text/css" href="jQuery/ui.css"/>
    <script src="jQuery/jquery.js"></script>
    <script src="jQuery/jquery-ui.js"></script>
 Html : 
    <input type="text" id="date" />
 Javascript : 
    $( "#date" ).datepicker();
就大功告成

以下為一些實用 Datepicker 參數
$('#date').datepicker({
    showOn: 'both',              // 顯示按鈕圖示
    changeMonth: true,
    changeYear: true,
    dateFormat:'yy-mm-dd',       // 預設為 mm/dd/yy
    firstDay: 1,                 // 這裡 first day 指的是一星期的第一天,1 = 星期一
    minDate : "+1d",             // 限制最早日期
    maxDate : "+300d",           // 限制最晚日期
    buttonImage: 'calendar.gif'  // 按鈕圖示
});

參考網站
http://www.runoob.com/jqueryui/jqueryui-use.html
https://blog.wu-boy.com/2008/04/jquery筆記-好用的日期函式/
http://pclevinblog.pixnet.net/blog/post/381097399-jquery-datepicker-設定限制日期最小最大-mindate-max

2018年9月20日 星期四

網頁開發(3) 重複查詢同一資料表

對同一個資料表做重複查詢


有時候可能會對同一個資料表做重複查詢很多次
也就是需要 JOIN 兩次以上

例如( 以下範例不小心用到中文,沒試過到底可不可行 )
Table1
Table2








這時可能就需要 JOIN Table2 重複 2 次來達到完整資料
利用 AS 來達到區分 Table2 達到 JOIN 2 次的效果
    SELECT send.名稱 as sendman, recv.名稱 as recvman
    FROM Table1 as log
    LEFT JOIN Table2 AS send ON log.寄件者 = send.id
    LEFT JOIN Table2 AS recv ON log.收件者 = recv.id

2018年9月11日 星期二

使用 IE 的理由

在公司內部系統,網站會建議使用 Internet Explorer 開啟
原因很簡單,在 IE 裡,一個 html link 可以開啟相同 domain 下的資料夾和檔案
基本上大部分的瀏覽器都會檔,因為安全性的問題。

以 Chrome 為例
<a href="file:///fileserver/test.xls">Test</a>





IE 可以直接 Server 上的分享資料夾
只要連結可以轉成 UNC ( Universal Naming Convention )
並在相同 domain 下,Firefox 似乎也行但我沒試。

2018年9月10日 星期一

英文歌詞翻譯 Fall Out Boy - Centuries

Some legends are told
有些傳奇被傳誦
Some turn to dust or to gold
有些則灰飛煙滅或變成黃金
But you will remember me
但你會記得我
Remember me for centuries
生生世世都會記得我

And just one mistake
只要一個錯誤
Is all it will take
一切就功虧一簣
We'll go down in history
我們會名留青史
Remember me for centuries
永生永世地記住我
Remember me for centuries
永生永世地記住我

Mummified my teenage dreams (註一)
將年輕時的夢想像木乃伊一樣塵封
No, it's nothing wrong with me
不,我一點也沒錯
The kids are all wrong
錯的是那些孩子們
The story's all off
童話故事早已被扭曲 (註二)
Heavy metal broke my heart
重金屬狠狠敲擊我的心 (*1)

Come on, come on and let me in
來吧,來吧,讓我加入
The bruises on your thighs like my fingerprints
妳大腿上的瘀青簡直就像我的指紋
And this is supposed to match
而且應該是吻合的
The darkness that you felt
妳所感受的黑暗
I never meant for you to fix yourself
我從沒要妳獨自面對 (註三)

And I can't stop 'til the whole world knows my name
在我名揚千里前我不能停下
'Cause I was only born inside my dreams
因為我跟我的夢想共存亡  (*2) 
Until you die for me, as long as there's a light, my shadow's over you
直到妳為我粉身碎骨,只要有一絲光芒,妳便會被我壟罩在我的陰影下
'Cause I, I am the opposite of amnesia (註)
因為我就是遺忘的相反詞
And you're a cherry blossom
而妳如含苞待放的花苞 (註)
You're about to bloom
即將綻放
You look so pretty, but you're gone so soon
妳是如此美麗,但卻稍縱即逝

We've been here forever
我們就是永恆的存在
And here's the frozen proof
而這就是時間凍結的證明
I could scream forever
我可以嘶喊到永遠
We are the poisoned youth
我們是青春被染色的青年


註解 :
    一 · Mummy   :   木乃伊
    二 · off             :   偏離、情況不好
    三 · fix              :  (目光等)注視
    四 · amnesia   :   失憶
    五 · cherry       :   (處女身分) One's virginity

*
     1.  Heavy metal broke my heart

          這裡我翻 "重金屬狠狠敲擊我的心" 大意是因為他認為大家都是錯的,
          只有重金屬才能將他拉到  "現實"。這裡的 broke my heart 應該是指物理上的...
          加上翻完後感覺的意境,陰影壟罩、時間凍結(死亡)、scream forever、poisoned youth
          整首歌有點像影射 科倫拜校園事件

     2.  only born inside my dreams

          這我照字翻翻不出來,是前後推敲自己認為的,但 born 有天生的概念在,
          加上參照 born of 這片語材這要翻的。

參考資料 :
https://songmeanings.com/songs/view/3530822107859490084/
因為翻完真的很怪尤其是 Heavy metal broke my heart ,才去找歌詞意思,後來發現這個網站,覺得這個最說服我。網站寫的大概講的就是這首歌其實是以校園槍手的視角去描述的,看完後我就不敢跟著唱了...,尤其是 Come on, come on and let me in ,X的 !! 有夠變態。

2018年9月7日 星期五

英文歌詞翻譯 Bruno Mars - Finesse


Ooh, don't we look good together?
我們看起來是不是很棒?
There's a reason why they watch all night long
這就是為何他們整晚都看著我們的原因
Yeah, know we'll turn heads forever
我們永遠都是全場焦點(註一)
So tonight I'm gonna show you off
今晚我會好好地炫耀妳

When I'm walkin' with you
當我和妳走在一起
I watch the whole room change
我發現全場氣氛都變了
Baby, that's what you do
寶貝這都是因為妳
No, my baby, don't play
不寶貝這是真的
Blame it on my confidence
都怪我的自信
Oh, blame it on your measurements
和怪妳那魔鬼的身材
Shut that shit down on sight
立刻把煩人的事物拋到一邊(註二)
That's right
這就對了

We out here drippin' in finesse
我們在這裡慢慢沉浸在舞步當中(註三、四)
It don't make no sense
令人難以置信
Out here drippin' in finesse
在這沉浸於舞步中
You know it, you know it
你知道的,你知道的
We out here drippin' in finesse
我們在這裡慢慢沉浸在舞步當中
It don't make no sense
令人難以置信
Out here drippin' in finesse
在這沉浸於舞步中
You know it, you know it
你知道的,你知道的

Now slow it down for me baby
現在慢下來我的寶貝
'Cause I love the way it feels when we grind
因為我喜歡我們彼此磨蹭的感覺
Yeah, our connection's so magnetic on the floor
我們在舞池中像磁鐵一樣密不可分
Nothing can stop us tonight
今晚沒有任何東西可以阻止我們

Fellas grab your ladies if your lady fine
男士們如果你的女伴很棒就摟著她
Tell her she the one, she the one for life
告訴她是你的唯一,生命中的唯一
Ladies grab your fellas and let's do this right
女士們帶著妳的男伴讓我們跳舞吧
If you're on one like me in mind
如果他是跟我想的真命天子一樣
Yeah, we got it goin' on, got it goin' on
我們繼續跳舞,繼續跳舞
Don't it feel so good to be us, ay?
像我們這樣部是很好嗎?
Yeah, we got it goin' on, got it goin' on
我們繼續跳舞,繼續跳舞
Girl, we got it goin' on
女孩,我們繼續跳舞
Yeah, we got it goin' on, got it goin' on
我們繼續跳舞,繼續跳舞
Don't it feel so good to be us, ay?
像我們這樣部是很好嗎?
Yeah, we got it goin' on, got it goin' on
我們繼續跳舞,繼續跳舞


註解 :
    一 · turn heads  :  另人轉頭 = 引人注目
    二 · on sight       :   立即、立刻
    三 · drippin' in  :  潺潺、形容液體緩緩地流
    四 · finesse         :  技巧(這裡翻舞步)

2018年8月24日 星期五

網頁開發(2) 利用 Ajax 取的 PHP 值

網頁開發我常利用 Ajax 來連接 PHP以便撈取後端資料

但是 PHP 傳回來的值會是 String 值

JavaScript 每個參數都是一個物件,所以辨認不出 PHP傳回來的值

這時就需要 json 來達到取值的效果

首先是 JavaScript 的 Ajax
var wanteddata;
var requert = $.ajax({
    type: "POST",
    async: false,
    url: "/function/getData.php",
    dataType: 'json',
    data:{id:msg},
    success: function(data){
        wanteddata = data.value; //有些可能要自己 json_decode
    },
    error: function(data,status,e){
        alert('Get Data Error!');
    }
});
再來是 PHP 端 ( getData.php )
<?php
    $value = "IamData";
    $ReturnValue = array("value"=>$value);
    echo json_encode($ReturnValue);
?>
參考資料 : 我的同學

IPv6 筆記 ( 序 + week1 )

工作需求必須從頭到尾了解 IPv6 這項技術

所以好像回到大學時期,重新看了 NTHU 黃能富教授經營的學聯網 ( 課程已關閉 )

但既然重看了,那就索性作筆記但不會太詳細 ( 因為沒人會考我XD )。

參考資料

Week 1 

1. IPv6 之於 IPv4

(1) 提供大量 IP 位址,加速連線 ( 因為位址明確 , 無須 NAT...等技術 )

(2) 精簡 Header ( 因為各Layer功能漸強可以 Cover 或用其他方法表示 )
          
          i.   Header 長度固定 ( 40 bytes )
          ii.  移除 checksum ( Layer2可以做檢查 )
          iii. 移除切割封包功能 ( Source 端自己做 )

(3) 利用 Extension Header 來完成 IPv4 的 Option 功能 ( Ex.RoutingHeader、FragmentHeader ... )

2. IPv6 Addressing

(1) 3種位址 Unicast ( 傳給指定位址 )、Multicast ( 傳給指定某群位址 )、Antcast ( 誰都可轉送 )

(2) IPv6 表示法 (128 bits)

          i.   FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
          ii.  1080:0:0:0:8:800:200C:417A
          iii. 1080::8:800:200C:417A ( 用連續兩個冒號表示連續 16 bits的0 , 但若有2組以上則不行,因為不知道長度 )

(3) Addresses Formats


3. IPv6 功能

(1) ICMPv6 ( Internet Control Message Protocol ) 的功能


(2) Supports IGP (Interior Gateway Protocol) and EGP (Edge Gateway Protocol)

          i.   IGP -> RIPng(RFC 2080)、OSPFv3(RFC 2740)
          ii.  EGP -> MP-BGP4(RFC 2858 and RFC 2545) 、 BGP4+

(3) Plug-and-Play ( Auto Configuration )

          i.   電腦會自動 註冊和產生所有連網必要之參數
          ii.  可以隨時變更 ISP provider
          iii. 可以擁有多個IPv6位址、 IPv6位址有有效期限 
          iv.  2種 modes : stateless 跟 stateful ( using DHCPv6 )
          
          流程 : 自動產生 link-local address ( FE80:: + 48bits Ethernet address )
                     加入一個 All nodes 的 Group 已收到Group裡的訊息 ( FF02::1 )
                     發送 Solicitation Message 到 Router 的 Group ( FF02::2 )
                     Router 發送 Router Advertisement ( 裡面包含Router給的IPv6位址 )

4. Basic Algorithm

(1) 利用 ICMPv6 達到 ARP 的效果 ( Neighbor Solicitation... )

(2)  HOST 擁有 4 個 cache

          i.   The desination's cache ( 紀錄 目的地的 IP 跟 經過的 IP )
          ii.  The neighbor's cache   ( 紀錄  Neighbor's IP 跟 MAC )
          iii. The prefix list  ( 相連Routers 給的 prefix )
          iv.  The router list  ( 相連Routers )

(3) 送封包流程

          i.   先找 The desination's cache 
          ii.  再找 The prefix list ( 看是否在同個子網路下 )
          iii. 透過 Router 發送並更新 cache

5. IPv6 Flows and Flow Label

(1) IPv6 Real-time Support ( 用不同 Flow 來達到 Priority 的效果 )

6. IPv6 Security Support

(1) 所有 IPv6 封包都需要支援 authentication 跟 encryption Headers

2018年8月23日 星期四

BCB 筆記11 (ComboBox OnChange)

有時候會希望 ComboBox Change 的時候

Grid 能自動更新,但 ComboBox OnChange() 似乎事件較弱

所以 OnChange() 執行後,Grid 並沒有立即更新

你必須點 Grid 一下才會更新,當然一定有正規解法

但我很急無法深入研究,所以用這個邪門歪道


1. 首先創一個 Button1 並設定 OnClick 事件 (為了美觀你可以設Button1隱藏)

void __fastcall TMainForm::Button1Click(TObject *Sender)
{
    Grid->Refresh();
}

2. 在你想要的 ComboBox OnChange() 改為 Button1Click()


參考資料 : 著急的我

Windows 工作排程失效

會接觸這個東西是因為要寄系統信

系統信我的實作方法是用 工作排程 時間到就執行對應的 PHP 檔

執行檔是沒問題的,但是排程出問題了

排程總是被略過,好像沒有這回事一樣

我有找到很多方法,但只有這個有效,參考資料裡也有講其他方法

這是我解掉這個方法的圖片 ( 取自參考資料做備份 )


參考資料
https://dotblogs.com.tw/daniel07793/2012/05/07/72002

2018年8月22日 星期三

BCB 筆記10 (Grid 載圖片)

表格填圖片
下面示範 DrawGrid 填圖片 ( 其實 StringGrid 也可以 )

void __fastcall TMainForm::DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
    TDrawGrid *drawgrid = dynamic_cast<TDrawGrid *>(Sender);

    Bitmap->LoadFromFile(ExtractFilePath(Application->ExeName)+__PicturePath+"123.bmp");

    drawgrid->Canvas->Draw(Rect.Left, Rect.Top, Bitmap);

    delete Bitmap;
}

依照圖片大小的方法

    drawgrid->Canvas->StrenchDraw(TRect ,Bitmap);

參考資料
1. 我
2. https://bbs.csdn.net/topics/30220802

2018年7月1日 星期日

BCB 筆記9 (String Replace)

既然使用 BCB 作為開發工具
不免俗就會常常使用他們的 String
這裡介紹 BCB 取代字串的方法
StringReplace(const UnicodeString Source, const UnicodeString OldPattern, const UnicodeString NewPattern, TReplaceFlags Flags);


    String Str;
    TReplaceFlags rf = TReplaceFlags()<<rfReplaceAll;
    Str = StringReplace(Str, L"@", L"\n", rf);


這裡的 TReplaceFlags 有兩種
rfReplaceAll -> 有這個參數會取代全部,無則只取代第一個
rfIgnoreCase -> 有這個參數會無視大小寫,無則會分辨大小寫

參考資料
http://www.cppfans.com/cbknowledge/reference/strings/stringreplace.asp

BCB OLE操作EXCEL(3)

在用 OLE 操作 Excel 時
有可能會遇到剪貼簿裡的資料過大
導致關閉 Excel 時跳出視窗警告
"是否放棄剪貼簿裡的資料"

要避開的話通常會用關閉 DisplayAlert 的方法來避免
但我常常失敗,原因不明。

所以給失敗的朋友另一個辦法
在 Excel 關閉前複製一格 避免剪貼簿裡資料過多跳出視窗


void __fastcall Excel::Close_2(){
    Exc.Range = Exc.WorkSheet.OlePropertyGet("Cells", 1, 1);
    Exc.Range.OleFunction("Copy");
    Exc.WorkBook.OleFunction("Close", false);
    Exc.App.Exec(Procedure("Quit"));
}

上一篇:
BCB OLE操作EXCEL (2)

2018年6月10日 星期日

BCB 筆記8 (Compile)

我在寫程式的時候
偶爾會想寫個固定字串在 Header (路徑之類的)
但這會在 Compile 上造成很大的負荷
Cannot create pre-compiled header: initialized data in header
因為我的 Header 都寫在一起


    const String __SavePath = "Save\\";
    const String __NameCardPath = "NameCard\\";
    const String __PicturePath = "Pic\\";

所以 Header 必須分開
但最好是改讀檔的

但我因為這個發現了一個講解 Compile 的網頁
在此留個紀錄
http://bcbjournal.org/articles/vol4/0005/Pre-compiled_header_tips.htm

BCB 筆記7 (StrToInt)

報告在製作時,一定會遇到要字串轉數字
在 BCB 裡有方便的函式

常見的有

    String str = "123"
    int x = StrToInt(str);
    float y = StrToFloat(str);

但有時候不一定可以轉成數字
這時就可用

    String str = "@123"
    int x;
    float y;
    bool z;
    z = TryStrToInt(str, x);
    z = TryStrToInt(str, y);

2018年6月3日 星期日

BCB 筆記6 (Sender)

說來慚愧,但我很後面才知道這東西
BCB 設計按鈕不外乎 TButton TBitBtn TSpeedButton

但按鈕通常邏輯差不多,只是因為傳的值不一樣而用不同 Button
然後程式碼變成這樣


void __fastcall TMainForm::TButton1Click(TObject *Sender)
{
    MyButtonFunction("TButton1");
}

void __fastcall TMainForm::TButton2Click(TObject *Sender)
{

    MyButtonFunction("TButton2");
}

void __fastcall TMainForm::TButton3Click(TObject *Sender)
{

    MyButtonFunction("TButton3");
}
但你其實可以

void __fastcall TMainForm::ButtonClick(TObject *Sender)
{
    TControl *btn = dynamic_cast<TControl *>(Sender);
    MyButtonFunction(btn->Name);
}
然後再去修改三個 Button 的 OnClick 指向 ButtonClick
這裡為什麼用 TControl 因為一次就可以相容三種 Button
用了半年BCB才知道...

BCB 筆記5 (TValueListEditor)

轉報告下一步就是自動產生報告
要自動產生報告,不外乎就是填表格。

你可以用 DrawGrid 或 StringGrid 來製作表格
但我認為 DrawGrid 和 StringGrid 都是完成度很高的元件
完成度很高代表若目的與設計方向不同,用起來就會綁手綁腳
要覆寫很多功能或者沒有與你目的相同的東西

我想當初 Grid 就是來完成表格,不是給你填,
所以在填值方面不會有太多方便的功能。
填表格通常會想要用下拉式表單 ( ComboBox )
網路上找想用 Grid 來做下拉式表單不外乎兩種
1. 創一個 ComboBox 但"位置"在 Grid 的該 Cell 上
2. 在該 Cell 真的創一個 ComboBox

但我兩種都不用
我這裡要介紹的元件是 TValueListEditor 來 Implement 我要給填的表格
TValueListEditor 只有兩個 Column 一個 Key 和 Value
所以要三欄的你只好乖乖用他給 Grid 元件,或者用CustomGrid 自己做一個 Grid

但 TValueListEditor 她有 EditStyle 可改,讓你的表格更靈活

void __fastcall MyValueListEditorClass::setDropList(TValueListEditor* List, int index, TStringList* li){
    List->ItemProps[index]->EditStyle = esPickList;
    List->ItemProps[index]->PickList = li;
    List->ItemProps[index]->ReadOnly = true;
}
我將 EditStyle 變成 esPickList 就等於是下拉式表格
表格內容就是 PickList (TStringList*)
我覺得比用 Grid 方便許多,結果如下
有些人(我)會想刪掉 TValueListEditor 上面的 FixRow
但是我找了很多方法都不行,最後只能開大絕

    MyValueListEditor->RowHeights[0] = 0;
輕鬆!!!

2018年5月6日 星期日

BCB 筆記4 (DrawText)

在 BCB 裡設計表格類的東西
幾乎都是從 TCustomGrid 繼承而來
在填入表格值都是用 DrawText 來填值
而我們要改變一些東西,例如文字置中
就要自己下 DrawText 的參數

首先第一步,把 DefaultDrawing 的值改為 Fault
不改的話會 DrawText 兩次,造成重疊

第二步改寫 OnDrawCell

void __fastcall TMainForm::LGridDrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
    TStringGrid *vle = dynamic_cast<TStringGrid *>(Sender);
    int flag = DT_WORDBREAK+DT_CENTER+DT_VCENTER+DT_SINGLELINE;
    vle->Canvas->FillRect(Rect);
    vle->Canvas->Font->Size = 11;
    vle->Canvas->Font->Style = TFontStyles() << fsBold;
    vle->Canvas->Pen->Color = clBlack;
    vle->Canvas->Rectangle(Rect);
    String Str = vle->Cells[ACol][ARow];
    DrawText(vle->Canvas->Handle, Str.w_str(),Str.Length(), &Rect, flag);
}


首先要通用的話,就必須用 Sender 來判斷呼叫的 TStringgrid
再來調整 Flag 來改寫置左中右,上下置中似乎只對單行有作用
接下來就常見的 Font 的操作,最後 DrawText 便大功告成

BCB 筆記3 (TSpeedButton)

在 BCB 裡 Button 我常用的是 TSpeedButton

1. 可以載入圖片( TButton不行 )。
2. TSpeedButton 屬性裡有 GroupIndex 可以集合一群 TSpeedButton 成一個群組,同個群組後,
    一個群只能有一個被選取,被選取的 TSpeedButton 的 Down 值為 TRUE ,為選取則為
    FALSE。
3. 有 FLAT ( 滑鼠移上去會有浮起來的效果 ),對於單人開發的程式,這可以讓你的 Button 看
    起來比較有質感。

2018年5月1日 星期二

心情日記 2018/05/01

距離上次寫 BLOG 過了三個禮拜

看來維持寫 BLOG 真需要些意志力跟重訓一樣

不知不覺進入職場半年 (3天特休 GET!!)

但依然跟標題一樣,總覺得繼續做這個不行沒前途要換

但又沒本錢換QQ

今天想想後又回來寫 BLOG,充實自己

樂觀點的話就是我又繼續寫 BLOG 沒浪費這個得來不易的假日

希望自己不要鬆懈太久,維持住這個習慣

網頁開發(1) 使用 IE 瀏覽器時 Javascript 失效

我本人非專業寫網頁,大學沒寫過是進公司才學的,因為沒人維護XD
公司常用瀏覽器是 IE,因為IE可以直接讓你以檔案總管的方式直接開啟 file://... 的超連結,其他瀏覽器都會擋,詳細原因我不知道,但這個可以讓你方便調用 SERVER 上資料,方便很多,其實其他瀏覽器也可以辦到,但要做設定,但不可能你叫公司員工都做這設定,所以大家都用 IE,離題了...

JS 檔放到 Server 後無反應

    我自己在寫程式時,第一個問題是為什麼我改.JS檔放到SERVER後無反應
這裡無反應是指像什麼都沒改過一樣,搞了很久才發現原來 .JS檔會被瀏覽器存進快取
所以只要檔名一樣,他就會跑之前的.JS 造成所謂無反應。
 src="xxxx.js?2018032833"
想要解決又不想改檔名就靠這個加流水號,簡單又方便

為什麼我的 IE 可以跑,別人的不行

    但這個又讓我引來第二個問題,為什麼我的IE可以跑,別人的不行
後來發現因為我對第一個問題有陰影,所以我總是進入開發者模式(IE 按F12)
IE只有在開發者模式才會認識 Javascript 的 console 這個物件
沒開啟就不認識 console 導致 Javascript 失效
所以放進 SERVER 前刪除所有 console 才是唯一解

IE 讀不了 JS,報錯

    有可能原因跟 CSS 一樣,用版本過舊的 IE 去讀取,可以參考這篇 CSS 在 IE 瀏覽器下失效

BCB OLE操作EXCEL(2)

BCB 操作 EXCEL、WORD ( OLE的應用 )


有時候再操作 EXCEL 和 WORD 的時候,有可能會要應用到 MultiProcess 的概念
但真正需要的地方很少,我自己是用偷懶的方式來避開,
因為互相搶奪導致資料錯誤出現的機率微乎其微。
下面介紹一些我常碰到的錯誤
bool __fastcall JunYe_Word::getDataTable(int index){
    Variant Range;
    bool flag = true;
    try{
        Range = Wd.DataDoc.OlePropertyGet("Tables").OleFunction("Item",index).OlePropertyGet("Range");
    }catch(EOleSysError *e){
        BugReport(L"Ranging Fail !! This Word doesn't have No."+IntToStr(index)+" Table.");
        flag = false;
    }
    if(flag){
        Range.OlePropertyGet("Rows").OleFunction("Item",1).OleFunction("Delete");
        Range.OleFunction("Copy");
    }
    return flag;
}
有時候要 Range 但 FAIL,有可能資料錯誤或跳錯誤訊息,且造成程式當掉的機會很大
這時候就會用 Try and Catch 如上面的程式碼來避免
String __fastcall Excel::getCellValue(int row, int column){
    String data;
    Variant temp;
    try{
        temp = Exc.WorkSheet.OlePropertyGet("Cells", row, column).OlePropertyGet("Value");
        if(VarType(temp) != varError){
            data = temp;
        }
    }catch(EOleSysError *e){
        BugReport(L"The Cell Can't transmit to OleStr");
    }
    return data;
}
這個段程式是防止吃 EXCEL CELL的值時,會導致 Can't transmit to OleStr 的狀況, 不是吃錯值,而是格子可能是#FFFFFF之類的東西,你直接用上述的data(String)去接會錯 Try and Catch 也擋不了( 我自己試擋不了 ),這時我用多了一層判斷, 用 VarType 去檢查 CELL 值是否能轉 OleStr。

上一篇:
BCB OLE操作EXCEL (1)
下一篇:

2018年4月8日 星期日

.ini 檔案 操作及應用

ini檔顧名思義就是拿來初始化的
#include "inifiles.hpp"
TIniFile *IniFile;
IniFile = new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));
IniFile->WriteString(category, parameter, value);
delete IniFile;
這裡介紹其中一個我最常用的 WriteString
可以看到它要傳入三個參數
這裡用圖片介紹

AnsiString __fastcall INI::ReadStr(AnsiString category, AnsiString parameter)
{
    AnsiString value;
    TIniFile *IniFile;
    IniFile = new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));
    value = IniFile->ReadString(category, parameter, value);
    delete IniFile;
    return value;
}
第三個value指的是若沒值時的 Default

這裡想寫一些使用心得
ini 檔及其操作十分簡單但功能就是這樣,他不會有 SORTING 之類的功能
最多查詢有無值而已,你不能問它"你有什麼值?"
ini 檔紀錄的都是 "已知" 的資料,所以正常不會用它來找"未知"資料
你不會不知道 ini 資料全貌
要想用 ini 做簡單紀錄未知資料之類的,你只能做些設計讓 ini 可以記錄未知
例如利用某一 category 來記錄 ini 的資料全貌
達到"你"不用知道資料全貌,但其效用不會比你用其他像 XML 之類的方便

BCB 筆記2 (TDateTime)

BCB TDateTime 時間操作及應用

在 BCB 裡有關時間的操作幾乎都是與 TDateTime 這個 Class 相關
若找不到相關資料可以用 BCB 的 HELP
( 游標移到要查詢的函式或Class 並按 F1 )

介紹幾個個人有在用的函式
TDateTimePicker->DateTime = Now();
TDateTimePicker->DateTime.DateTimeString();
TDateTimePicker 是常用的 BCB(VCL)元件
可以讓使用方便選擇日期+防呆

String date = "2018/4/8";
StrToDate(date);
將字串轉為 TDateTime 格式
double(TDateTimePicker1->DateTime)-double(TDateTimePicker2->DateTime)
直接代入double() 就可使 TDateTime 量化
這裡 double() 後的數值基本單位是天
1.5 = 一天半

參考資料
1. http://yanphph.blogspot.tw/2009/01/bcb-vcl.html
2. http://cshartuc.blogspot.tw/2016/10/bcb.html

2018年4月1日 星期日

BCB 筆記1 (MessageBox、ComboBox)

寫有介面的程式時常會需要跳出訊息
這裡介紹Application->MessageBox int MessageBox(const char* Text, const char* Caption, int Flags);

這裡沒啥好講的
想寫的幾乎都會變照抄網上的東西,所以就給連結當備份吧
1. http://yanjuns.blogspot.tw/2015/06/cbuilder-vcl.html
2. http://nelson.pixnet.net/blog/post/217684-%5Bbcb%5D-messagebox-%E7%9A%84%E5%8F%83%E6%95%B8%E8%AA%AA%E6%98%8E


如何令 ComboBox 顯示的字不會被更改

答案就是將 ComboBox style 屬性改為 csDropDownList
因為我總是用 BCB10 給的元件去設定 ( Object Inspector )
所以再寫新程式的時候,總忘記當初怎改的
( 因為公司並不會一直要求我去寫資料彙整的程式,久久寫一次 )

令 ComboBox 顯示的字不會被更改

深入了解 ComboBox 後來發現另一招
當 ComboBox 顯示框文字被修改時
會自動尋找是否為 ComboBox 其中一個 Item
是 ItemIndex 修改為該Item 的
否 ItemIndex = -1
此為 BCB10 程式碼
int tempindex;
void __fastcall TMainForm::CSTestSiteComboBoxChange(TObject *Sender)
{
    if(CSTestSiteComboBox->ItemIndex == -1){
        CSTestSiteComboBox->ItemIndex = tempindex;
    }
    tempindex = CSTestSiteComboBox->ItemIndex;
}
如上所示
文字被修改後若不屬於原有 Item (也就是ItemIndex == -1)
修改回來後達到類似無法修改的效果
通常不給修改是為了防呆
所以只能顯示範疇內的東西也是防呆的一種

BCB OLE操作EXCEL(1)

BCB 操作 EXCEL、WORD ( OLE的應用 )


之前有講工作關係需要彙整報告,報告不外乎 WORD、EXCEL、PDF檔

程式要操作 WORD、EXCEL 可以靠微軟的
COM(Component Object Model)或 .NET Framework.
照理說應該要用 .NET Framework ( 比較潮?? ) 但是公司前輩使用的是 COM
新人啥都不懂乖乖跟著學就對了,其實也不知道兩者實際差異
因為從來沒試過另外一種XD

在 COM 的基礎下,OLE ( Object Linking and Embedding )就是我們要用的技術
簡單來說就是把應用程式 ( EXCEL、WORD ) 物件化後給軟體使用
所以在這基礎下達到操作 EXCEL、WORD 和兩者間的溝通操作

這裡使用的 IDE 是 BCB10 拿 EXCEL 作範例

#include "Comobj.hpp" //操作EXCEL
struct _Excel
{
        Variant App;
        Variant WorkBooks;
        Variant WorkBook;
        Variant WorkSheets;
        Variant WorkSheet;
};
首先宣告 Variant 去承接OLE的EXCEL物件
Excel::Excel(){
        Exc.App = CreateOleObject("Excel.Application");
        Exc.App.OlePropertySet("Visible", true);
        Exc.WorkBooks = Exc.App.OlePropertyGet("Workbooks");
}
void __fastcall Excel::Open(AnsiString path){
        Exc.WorkBook = Exc.WorkBooks.OleFunction("Open", OleStr(path));
        Exc.WorkSheets = Exc.WorkBook.OlePropertyGet("Worksheets");
        Exc.WorkSheet = Exc.WorkSheets.OlePropertyGet("Item", 1);
}
void __fastcall Excel::Close(){
        Exc.WorkBook.OleFunction("Close", true);
        Exc.App.Exec(Procedure("Quit"));
}
這裡我分三個FUNCTION 來模擬平時操作EXCEL的狀態( 對我來說直觀好理解 )
constructor 產生EXCEL物件,並開啟工作簿集合( 工作簿想像是EXCEL的外框 )
open            開啟路徑的EXCEL,並在工作表集合要編號為"1"的工作表
close            關閉工作簿,這裡第一行 CODE 代表意義是不儲存就關閉

這裡有個重要東西先講
OLE 物件吃的是 Wide String,這裡用的是萬能的 OleStr() 轉成 Wide String
我從 BCB10 的 UnicodeString 轉過去吃盡苦頭
這時去問了那個唯一可以問的前輩才知道有這個函式,那時真覺得他是活菩薩。
關於 Wide String 和 UnicodeString 的轉換以後再寫一篇

( PS 以下是我的體感,有錯我道歉
關於 OLE 網路上的資源並沒很多
第一個 BCB10 沒人用 (沒有當初BCB6那麼猛),要用都用 Visual C++ 去寫
第二個 OLE 也是一個快被替換的東西
所以用 BCB10 去寫這東西,上網查都是 BCB6 的CODE
所以要注意的是 BCB6 跟 BCB10 字串的差異 )


下一篇:
BCB OLE操作EXCEL (2)

參考來源:
1. http://skybow.pixnet.net/blog/post/98858843-%5Bbcb%5D%E7%94%A8c%2B%2B-builder%E6%8E%A7%E5%88%B6excel%E6%AA%94%E6%A1%88%E8%AE%80%E5%8F%96
2. https://zh.wikipedia.org/wiki/%E7%BB%84%E4%BB%B6%E5%AF%B9%E8%B1%A1%E6%A8%A1%E5%9E%8B
3. https://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1%E9%93%BE%E6%8E%A5%E4%B8%8E%E5%B5%8C%E5%85%A5

2018年3月29日 星期四

BCB 選擇路徑(資料夾)

BCB 選擇路徑(資料夾)


工作關係要將各式各樣的資料彙整並輸出
各式各樣的資料都放在同一目錄下
所以在設計程式就必須設計可以給使用者選擇目錄
但BCB10似乎沒有這種元件
(其實有 DirectoryListBox 但我駕馭不了)

於是Google發現大家用的是 SelectDirectory();
網路上大大們說有 2 種版本

Boolean SelectDirectory(AnsiString Directory, TSelectDirOpts Options, Longint HelpCtx);
Boolean SelectDirectory(const AnsiString Caption, const BSTR Root, AnsiString Directory, TSelectDirExtOpts Options = [sdNewUI], TWinControl * Parent = nil);

一個是 Windows 的對話框,一個是 BCB 自己的
但我試不出來兩個似乎都長一樣
不知道是 BCB10 的改動還是我用錯

以下是程式碼 ( 第2種版本 )
#include <vcl .filectrl.hpp>
void __fastcall TMainForm::BitBtn1Click(TObject *Sender)
{
    String str;
    TSelectDirExtOpts opt;
    opt += TSelectDirExtOpts()<<sdShowEdit;
    opt += TSelectDirExtOpts()<<sdValidateDir;
    if (SelectDirectory(L"Please Select a Directory", L"", str, opt, this))
        LabeledEdit1->Text = str;
}

SelectDirectory 共輸入了 5 個參數

第一個 Caption = 對話框顯示的字

第二個 Root = 根路徑

第三個 Directory = 選擇的字串

第四個 Options = 對話框樣式

第五個 不清楚,自己理解是 選擇 this 等於我按"這個" Button 這元件就會跳出來

其中 TSelectDirExtOpts 參數可以參考官方文件


參考資料
http://hcl123.blogspot.tw/2012/09/using-open-directory-dialog-box-in-bcb.html

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/FileCtrl_SelectDirectory@string@TSelectDirOpts@Longint.html

BCB Debug

BCB Debug


因為工作關係接觸了 BCB10
這是我人生中第一次學 C++
頁面打開其實不難理解但仍然迷茫了一星期
( 公司只有一個人會,不好意思一直煩他 )

雖然有強大的斷點功能
但我還是不太會用,應該說不習慣
加上我寫的都是小程式
所以我選擇寫一個TXT檔 來記錄LOG
程式碼如下
void BugReport(AnsiString msg)
{
    AnsiString Path = ExtractFilePath(Application->ExeName);
    Path.cat_sprintf("DeBug.txt");
    FILE *fp = fopen(Path.c_str(), "a+");
    if(!fp)return;
    fprintf(fp, "%s\n", msg);
    fclose(fp);
}

至於為什麼用 AnsiString
因為網路上大大們分享的程式碼都是 BCB6
也就是他們的 String 等於 AnsiString
而 BCB10 的 String 等於 UnicodeString
兩者有啥不同,我想痛過就知道

Hi

第一篇就來寫寫動機吧

如果改了部落格標題的話

寫這篇的時候標題應該是"沒有方向整天偷懶的工程師"

如標題所示

為了維持工作動能,記錄程式碼,以及工作上大大小小的事

我決定開始寫 Blog



期許

每六日早上都能更新一禮拜發生的事

沒寫希望是出國或很忙,而不是因為通宵打 PS4 或 POE


( PS. 這篇是上班打的,夠偷懶的吧! )


Popular Posts