2017年3月10日 星期五

SQL Server 2016 on Linux 使用上的限制

安裝好 SQL Server 2016 on Linux 之後,接下來就是要建立資料庫、建立資料表以及後續的管理工作。不過由於目前在 Linux 上還沒有官方版本的 GUI 管理工具,於是從 Windows 上用 SSMS 連線進去。連線的方法跟連線到 Windows 上的 SQL Server 相同。

經過幾番嘗試,目前發現使用 SSMS 管理 SQL Server 2016 on Linux 上的資料庫時,有以下的限制

  • 不支援用 SSMS 的圖形工具建立、檢視及修改
    1. 資料表結構
    2. 條件約束 (Constraint)
    3. 索引鍵 (Foreign Key)
    4. 資料表圖表

2017-03-10_065244

  • 不支援用圖形工具「編輯前 n 個資料列」,而且會造成 SSMS 閃退

而以下項目是可以使用 SSMS 的圖形工具建立、檢視及修改的

  • 資料庫
  • 索引 (Index)
  • 統計資料 (Statistics)
  • 檢視 (View)
  • 登入
  • 伺服器角色

2017年2月11日 星期六

於 .Net 4.5 使用 Crystal Report 的注意事項

最近接了一個定時抓資料產生報表的案子,想說應該很容易,沒想到卻因為 Crystal Report 的問題卡關了一整天

症狀是這樣的:服務一啟動就發生 1067 錯誤

2017-02-11_164847

看事件檢視器中的錯誤訊息是 System.IO.FileNotFoundException,但是卻不知道是哪個檔案找不到

2017-02-11_165040

卡了好幾個小時之後,轉個方向,改成用 Console 程式來產生報表,結果一跑就看到問題發生的原因了,是找不到這個檔案 "C:\Program Files (x86)\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Common\SAP BusinessObjects Enterprise XI 4.0\win32_x86\dotnet1\crdb_adoplus.dll"

可是根本就沒有這個目錄,怎麼可能找得到檔案呢?

2017-02-11_165541

把這個路徑拿去 google,一搜馬上就有結果了,原來要在 App.config 的 startup 節加上 useLegacyV2RuntimeActivationPolicy="true" 這個屬性。

也就是把
<startup>
改成
<startup useLegacyV2RuntimeActivationPolicy="true">

改好之後,重新建置,執行,果然正常了。
為免遺忘,特記述於此。

2016年9月17日 星期六

Arduino 霹靂燈實驗

  1. 功能簡介
    1. 使用 Arduino 控制 6 個 LED,造成霹靂燈的效果
    2. 使用電位器決定霹靂燈移動的延遲時間
    3. 將電位器輸入與延遲時間顯示在 LCD 顯示器上
  2. 電路連接
    1. LED 接於 Arduino 的 D2 至 D7,每顆 LED 均串接一個 220 歐姆 的限流電阻 
    2. 電位器中間接腳接至Arduino 的 A0 輸入,電位器兩端接腳分別接至 5V 與 GND
    3. LCD1602 透過 LCM1602 接至 Arduino 的 SDA (A4) 與 SCL (A5)

      Pili_Light_bb
  3. 程式
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    
    int ledPin[] = { 2, 3, 4, 5, 6, 7 };
    int delayMs;
    int i = 0, d = 1;
    
    // 設定 LCD 的位址、每行字數、行數
    LiquidCrystal_I2C lcd(0x27, 16, 2); 
    
    void setup()
    {
    // 設定輸出 pin 模式
    for (int i = 0; i < 6; i++)
             pinMode(ledPin[i], OUTPUT);
         // 初始化 LCD 顯示器
         lcd.init();
         lcd.backlight(); } void loop() {

         // 讀取電位器輸入
    delayMs = analogRead(A0);
         lcd.setCursor(0, 0);
         lcd.print("A0 = " + String(delayMs) + "   ");
    // 限制延遲的範圍
         delayMs = map(delayMs, 0, 1023, 5, 500);
         lcd.setCursor(0, 1);
         lcd.print("Delay = " + String(delayMs) + "   ");


         // 點滅控制
    digitalWrite(ledPin[0], 0 == i ? HIGH : LOW);
         digitalWrite(ledPin[1], 1 == i ? HIGH : LOW);
         digitalWrite(ledPin[2], 2 == i ? HIGH : LOW);
         digitalWrite(ledPin[3], 3 == i ? HIGH : LOW);
         digitalWrite(ledPin[4], 4 == i ? HIGH : LOW);
         digitalWrite(ledPin[5], 5 == i ? HIGH : LOW);
         delay(delayMs);
         i += d;
    // 換方向的控制
    if (5 == i)
             d = -1;
         else if (0 == i)
             d = 1; }
  4. 運行影片

2015年12月7日 星期一

Lazarus 系列–4. 連接資料庫

在 Lazarus 的世界裡,沒有 BDE、ADO、dbExpress 等 Delphi 世界裡的資料庫連接方式,內建的是 SQLdb。除了 SQLdb 之外,有一些第三方的資料庫元件廠商也推出了給 Lazarus 使用的連接元件,今天不談第三方元件,專談 SQLdb。

SQLdb 支援的範圍很廣,涵蓋了經常使用的各種資料庫,包括 MSSQL、MySQL、SyBase、PostgreSQL、Oracle、Interbase、SQLite 等,如果超過這些資料庫的範圍,還可以用 ODBC 來連接。而 SQLdb 的底層呼叫的則是各家資料庫提供的原生連接函式庫 (MSSQL 除外,底下會詳細說明)。

底下這張圖是 SQLdb 元件盤上的元件,其實可以完全只用前四個,後面的大多是各家資料庫專屬的連線元件以及管理元件,如果只需要做 CRUD 就可以不用管那些元件,而 CRUD 這四個動作幾乎已經涵蓋資料庫操作的 9 成以上了。

2015-12-06_023943

前四個元件由左而右分別是:

  1. SQLQuery:處理 CRUD 主要的元件
  2. SQLTransaction:處理 transaction 的元件,必要
  3. SQLScript:執行 SQL script 的元件
  4. SQLConnector:連接資料庫的元件,必要

其他的元件說明就請參照官網了。

 

剛才說到,SQLdb 的底層呼叫的是各家資料庫提供的原生連接函式庫,以在 Windows 平台上的 PostgreSQL 為例,呼叫的是 libpq.dll,一個比較方便的方法是下載 [easy_db_plus.zip],這是一個 demo 連結 PostgreSQL 的程式,解開之後,把所有的 dll 檔複製進 Lazarus 的安裝目錄以及你的專案目錄就可以了。

而 MSSQL 的狀況則不同,SQLdb 呼叫的並不是原生的 SQL Server Native Client,而是 dblib.dll,到 [這裡] 下載 dblib_current.zip 並解壓縮之後,將 dblib_XXXX.dll 以及 libiconv2.dll 複製進 Lazarus 的安裝目錄以及你的專案目錄,然後將 dblib_XXXX.dll 改名為 dblib.dll 就可以了。
(看你要連那一個版本的 MSSQL,目前是到 dblib_2008.dll,拿這個連 MSSQL 2012 也可以的)

 

接下來就以 MSSQL 為例子示範如何連接資料庫,並完成一個簡單的 CRUD 應用程式

  1. 放一個 SQLTransaction
  2. 放一個 SQLConnector,設定以下屬性:
    • Transaction 設定為 SQLTransaction1
    • ConnectorType 設定為 MSSQLServer
  3. 放一個 SQLQuery,設定以下屬性:
    • Database 屬性設定為 SQLConnector1,這時你可以觀察到 SQLQuery.Transaction 屬性也自動的被設定為 SQLTransaction1
    • PacketRecords 屬性設定為 -1 (MSSQL必須,其他資料庫可保持為預設值 10)
  4. 放一個 DataSource,設定以下屬性:
    • 設定 DataSet 屬性為 SQLQuery1
  5. 放一個 DbGrid,設定以下屬性:
    • 設定 DataSource 屬性為 DataSource1
  6. 放一個按鈕,撰寫 OnClick 事件如下:

    // 請將黃色字替換成你實際要用的值,可用 :port 來指定 MSSQL 偵聽的 port 號
    SQLConnector1.Close;
    SQLConnector1.HostName := '127.0.0.1';   
    SQLConnector1.DatabaseName := 'DB1';
    SQLConnector1.UserName := 'username';
    SQLConnector1.Password := 'password';
    SQLConnector1.Open;
    SQLQuery1.SQL.Text := 'SELECT * FROM TABLE1';
    SQLQuery1.Open;
  7. 編譯,執行,按下 Button1,若順利的話,可以看到 DbGrid 出現資料。如果出現連接失敗的訊息,請檢查 MSSQL 是否開啟了 TCP/IP 連線,以及 TCP 偵聽的 port 號

剛才完成的只有 CRUD 中的 R,接下來繼續完成 CUD 三部分

  1. 再放一個按鈕,撰寫 OnClick 事件如下:

    try
      SQLQuery1.ApplyUpdates;
      SQLTransaction1.CommitRetaining;
    except
      SQLTransaction1.RollbackRetaining;
      SQLQuery1.CancelUpdates;
    end;
  2. 編譯,執行,按下 Button1,在 DbGrid 上做新增、修改、刪除等動作,然後按 Button2,再去檢查資料,就發現資料已經異動了。
  3. 這種方法必須仰賴 table 本身有 primary key,才能正確的做出異動動作

但是如果 table 沒有 primary key,要如何做呢?SQLQuery 除了 SQL 屬性之外,還有 InsertSQL、UpdateSQL、DeleteSQL 三個屬性,請分別給這三個屬性設定正確的新增、修改、刪除的 SQL 敘述,參數部分用 : 開頭,原值參數用 :OLD_ 開頭 (必須是大寫)

需要更詳細的說明,請參閱 [官網]

這一期就講到這裡,下期再見

2015年11月18日 星期三

Lazarus 系列–3. Canvas 的使用

這一集用一個小程式來示範 Canvas 的使用,這個程式很簡單,就是用來模擬一種玩具「萬花尺

基本上,就是依據不同的參數畫出以下函數的圖形:

x := r1 * cos(θ * t1) + r2 * cos(θ * t2)
y := r1 * sin(θ * t1) + r2 * sin(θ * t2)

r1 = 大圓半徑,r2 = 小圓半徑
t1 = 大圓轉圈的速度,r2 = 小圓轉圈的速度

底下是幾個輸出的範例圖形

001

002

原始程式碼 在這裡下載,請大家自己研究一下囉

2015年11月4日 星期三

Lazarus 系列–2. 視窗畫面的佈局

Lazarus LCL 元件組的佈局,跟 VCL 很相似。為什麼說「很相似」呢?是 Lazarus 的 LCL 元件提供比 VCL 還要多,可以更方便的做好畫面的佈局。

 

一、Align 屬性:這個屬性指定了元件在 parent 中「怎麼靠邊」有以下幾種:

  • alTop:往上靠
  • alBottom:往下靠
  • alLeft: 往左靠
  • alRight:往右靠
  • alClient:填滿中間
  • alNone:都不靠
  • alCustom:這個不明白他怎麼靠,反正不是靠北靠木就是了 (VCL 沒有這個)

  來張圖就更清楚了 (為了方便看清楚 panel 的邊界,把每一個 panel 的 BevelWidth 屬性設定為 5)
2015-11-04_075758

  善用 Align 屬性可以很方便的給畫面佈局「切版」。

 

二、Anchors 屬性:Anchor 就是船錨,這個屬性用來指定元件在 parent 中「哪幾個邊要與 parent 同方向的邊保持固定距離」(以下稱為設定錨點),有以下幾種,均可以分別開啟與關閉:

  • akTop:上方保持固定距離,預設開啟
  • akBottom:下方保持固定距離
  • akLeft:左方保持固定距離,預設開啟
  • akRight:右方保持固定距離

來兩張圖示範一下效果

Panel1 把四個 Anchors 屬性都打開了,然後把 form 拉大,Panel1 的四個邊界依然與 form 的邊界保持固定距離。

2015-11-04_082421

2015-11-04_082852

Lazarus 的 Anchors 屬性除了把錨點設定在 parent 上以外,還可以把錨點設定在不是 parent 的元件上,還可以設定錨定時如何對齊,錨定時要留多少距離

2015-11-04_203829

這是 LCL 的錨點設定視窗,可以看到每一個方向都有 4 個設定項目:

  • Enabled:是否開啟這個方向的錨點
  • Sibling:我的兄弟是誰,就是我要跟誰錨定
  • 三個按鈕:如何對齊,有「對齊邊界」「依序排列」「對齊中線」三種
  • Border space:對齊邊界或是依序排列時要空出多少寬度

打個比方,將 Edit1 做如下的錨點設定之後,移動 Label1 時,Edit1 就會跟著移動:

2015-11-04_204701

Edit1 的上邊界與 Label1 錨定,對齊中線,同時左方也與 Lable1 錨定,依序排列,中間間隔 5px,這樣設定的結果如下圖:

2015-11-04_204911

把 Label1 抓著移動時,Edit1 會跟著移動,但是 Edit1 就無法被抓著移動了:

2015-11-04_204926

 

三、ChildSizing 屬性,這是容器元件才有的屬性,用來規範自己內部的元件要如何排列

2015-11-04_205231

  • ControlsPerLine:一列要排幾個元件
  • EnlargeHorizontal:自己被拉寬時,內部元件的寬度要如何變化
  • EnlargeVertival:自己被拉高時,內部元件的高度要如何變化
  • HorizontalSpacing:內部元件的水平間距
  • Layout:要怎麼排列內部元件
  • LeftRightSpacing:排列時,左右要空多少不拿來排列內部元件,就相當於 CSS 的 padding-left 與 padding-right
  • ShrinkHorizontal:自己被拉窄時,內部元件的寬度要如何變化
  • ShrinkVertival:自己被拉矮時,內部元件的高度要如何變化
  • TopBottomSpacing:排列時,上下要空多少不拿來排列內部元件,就相當於 CSS 的 padding-top 與 padding-bottom
  • HorizontalSpacing:內部元件的垂直間距

拿兩張圖來示範一下排列前與排列後,隨意擺放幾個元件,準備來排列

2015-11-04_205845

接下來,設定 Form1 的 ChilldSizing 屬性以及這些元件的 Z-Order 如下:
(設定 Z-Order 可以在 form 上選擇一個元件,然後使用 Ctrl-PgUp 與 Ctrl-PgDn 這兩個熱鍵來調整)

2015-11-04_210238

2015-11-04_210252

然後,這些元件就排列好了:

2015-11-04_210629

將 form 改變大小試試:

2015-11-04_210733

2015-11-04_210741

很方便,對吧!
可惜有一點,一個元件固定佔用一個「格子」,沒辦法跨列、跨欄,不過已經非常方便了!

這一篇就講到這裡,我們下期再見!

2015年11月1日 星期日

Lazarus 系列–1. 環境簡介

Lazarus 是一個 Open Source、跨平台的 Free Pascal 整合開發環境,可以稱得上是 Delphi 的 open source 替代品。詳細的歷程就請大家自行前往 Wiki官網 收看,這裡就不再多說了。

這一篇是介紹 Lazarus 的安裝與開發環境的巡覽

 

一、安裝

官網的下載頁 依據您的環境下載適當的版本,在 Windows 上安裝很簡單,就是下一步下一步而已,Linux 的使用者可能就稍微複雜一點,不同的發行版的安裝方式可能會有些不同。

安裝完成之後,首次執行會檢查必要的組件是否安裝,Windows 版本就不用煩惱,一定是全部都安裝好的,Linux 版本就要看一下了,可能要補安裝一些必要組件

 

二、開發環境巡覽

2015-11-01_214911

看到這個畫面,用過老版本 Delphi (D7及以前) 的人一定感到很親切,幾乎是一模一樣的嘛!接下來一個個視窗來說明

  1. 主功能表、工具列與元件盤
  2. 物件檢視器 Object Inspector
    顯示及修改目前選取到的物件的屬性、事件
  3. 專案檢視器 Project Inspector
    顯示專案的結構
  4. 程式碼編輯器 Source Editor
    這裡當然就是編輯程式碼的地方
  5. 訊息視窗 Messages
    顯示編譯輸出、錯誤訊息的地方
  6. 畫面設計視窗
    用拖拉方式來設計畫面的地方

看起來跟老版本 Delphi 幾乎都一樣,是吧!接下來說說跟 Delphi 不一樣的地方

  1. 可以編譯出 x86 與 x64 的應用程式,不過得安裝兩套,而且必須安裝在不同的目錄
  2. 原生支援 Unicode
  3. 程式碼編輯器採用的是 SynEdit 元件,比起 Delphi 的程式碼編輯器有蠻大的進步
  4. 程式碼的副檔名不同 dpr –> lpr、dfm –> lfm,故無法直接開 Delphi 的程式來編譯,必須經過轉換
  5. 熱鍵可以更改,也就是 Ctrl-Space 這個最常用的熱鍵可以改成別的,我個人是改成 Alt-Right (與 Visual Studio 相同)
  6. VCL 元件不是 100% 對應過來的,有些元件在 Lazarus 沒有,反之亦然
  7. 資料庫存取相關元件方面,沒有 BDE、ADO、dbExpress、FireDAC,也沒有 DataSnap,Lazarus 有一套自己的,叫做 SQLdb,支援的資料庫有 MSSQL、Sybase、MySQL、PostgreSQL、Firebird (Interbase)、Oracle、ODBC 和 SQLite,市面上常見的可以說都支援了。
  8. 對於檔案型資料庫的支援有 DBF、CSV、SDF(沒用過這個)、以及固定長度格式
  9. 安裝 package 必須重新編譯 Lazarus 開發環境
  10. 市面上的 3rd party 元件組,通常在 Lazarus 上不可用
  11. 其他還有很多,就請大家自己去發現了!

總之,要拿 Lazarus 來寫一些自己用的小程式,是完全可行的。如果要拿來寫商用軟體,則需要很大的努力,如果抱著「為什麼 Delphi 可以 Lazarus 不行」這樣的心態來對待 Lazarus,那就直接用 Delphi 就好了,不是嗎?

 

附記一:程式碼編輯器在 Linux 環境無法輸入中文的臨時解決方法

程式碼編輯器在 Linux 環境無法輸入中文,有一個勉強還可以接受的方法是按 Ctrl-Alt-T 熱鍵插入「ToDo」,輸入完之後再把
{ TODO : } 刪除掉
2015-11-01_220005

按下 OK 之後,就成了這樣
2015-11-01_220042