發表文章

目前顯示的是有「程式理論」標籤的文章

C# LINQ語法與SQL語法

圖片
  LINQ語法其實跟SQL語法還蠻像的,說蠻像基本上就是拿SQL語法來程式內使用而已。 學習過SQL的人太概都知道SQL的好處,雖說不上萬能,但是在找尋資料時卻是很好用的一種語法。 很多時候,不靠SQL資料庫要處理龐大內存資料真是一種痛苦,由其是不靠資料庫處理大量檔案資料或是內存資料時就是如此。如果有兩種資料須要JOIN就會需要很多程式碼,很多for/foreach迴圈去跑,因此總會希望程式碼在處理內存資料時會有像SQL這樣簡單的語法可以使用。 當然很多地方大都有在說LINQ和SQL的詳細寫法,我這邊也不再描述,我這邊主要是讓大家看看這兩種語法相似之處。 假如我有兩個資料表 學生基本資料(Student) 和 學等(Grade): Student StudentID Name Gender AddressCity AddressArea A0001 吳山汝 Female 台北市 萬華區 A0045 卓凱耀 Male 台中市 北區 A0107 劉立沛 Male 高雄市 鼓山區 Grade StudentID Class Score A0001 1.4 550 A0045 2.5 490 A0107 3.1 581 我們看看 幾個比較 假如我要選取學生資料表(Student)裏面的姓名(Name),然後過濾條件是住在台中市(AddressCity)會怎麼做呢? SQL語法: Select a.Name From Student a Where a.AddressCity = '台中市' 這三行分別就是: 選擇輸出的資料欄(Select) 資料來源(From) 過濾條件(Where) 注意: SQL對指令沒有大小寫分別,對字串不是使用雙引號,而是單引號 其中那個 a 是『別名』 如果用LINQ來寫,就會像如下: var result = ( from a in Student                       where a.AddressCity == "台中市"                      

C# 自訂 XCOPY 類別 :複製資料夾內所有檔案與子資料夾內容到目的資料夾(並覆蓋)

圖片
Xopy.class using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace Tools {     public class Xcopy     {         private string _message;         /// <summary>         /// 錯誤訊息         /// </summary>         public string Message         {             get { return _message; }         }         /// <summary>         /// 複製檔案群         /// </summary>         /// <param name="_source">來源資料夾</param>         /// <param name="_target">目的資料夾</param>         /// <param name="recursive">包含子資料夾</param>         /// <returns>成功 = 1 , 失敗 = -1</returns>         public int Copy(string _source, string _target, bool recursive = true)         {             try             {                 if (!Directory.Exists(_source))                 {                     _message = "來源資料夾不存在!";                     return

C# csv 檔匯入 List 一行搞定

圖片
  我有一個CSV 檔案(data.csv),內容大約如下: 編號,姓名,性別 T001,林黃頻,男 T002,江國勘,男 T003,劉簿相,男 所以,依照欄位我會定義出一個儲存用類別(Field.cs): namespace MyApp {     class Field     {         public Field(string Line)         {             var sp = Line.Split(',');             UserNo = sp[0];             UserName = sp[1];             Gender = sp[2];         }         public string UserNo { get; set; }         public string UserName { get; set; }         public string Gender { get; set; }                 public override string ToString()         {             string output =  UserNo+ "\t" + UserName + "\t" + Gender + "\r\n";             return output;         }     } } 主要程式碼其實只要一行就可以搞定(不含using) using System.IO ‧ ‧ ‧ // 這一行讀入CSV併排除第一行標題 List<Field> content = File.ReadAllLines("D:\\data.csv", Encoding.Default).Select(line => new Data1(line)).Skip(1).ToList(); // 顯示出來 foreach(Data1 item in totl) {      textBox1.Text += item.ToString(); } ‧ ‧ ‧

使用 NPOI 設定欄位(CELL)樣式與寬度

圖片
如何使用 NPOI 來設定CELL(欄位)的樣式:邊框、底色、字形,等等 底下是個 樣式類別檔案,把常用的欄位形態定義好,以後直接取用 DefXSSFstyle.cs using System.Drawing; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using NPOI.HSSF.Util; namespace XssSTYLE {     /// <summary>     /// 已經定義好的欄位樣式,如果需要新樣式,複製程式碼並賦與新名稱,修改樣式產生程式碼即可使用     /// </summary>     class DefXSSFstyle     {         /// <summary>         /// 抬頭樣式 - 01         /// 灰色底色,白色字,正黑體,無邊框         /// </summary>         /// <param name="wb"></param>         /// <returns></returns>         public XSSFCellStyle Banner01(IWorkbook wb)         {             XSSFCellStyle csh = (XSSFCellStyle)wb.CreateCellStyle();             csh.Alignment = HorizontalAlignment.Center;             csh.VerticalAlignment = VerticalAlignment.Center;             csh.WrapText = true;             csh.FillForegroundXSSFColor = new XSSFColor(Color.FromKnownColor(KnownColor.Gray));             csh.FillPattern = FillPattern.SolidForeground;             IFont f

關於 NPOI 取得 列 (Row) 和 欄(Cell) 數量

圖片
關於 NPOI 裏面如何取得 列(Row) 與欄(Cell)的數量。 NPOI 對於 IRow 或 ICell 沒有類似集合數量的 count 或是 length 可以取得, 可是相對的有 FirstRowNum / LastRowNum / FirstCellNum / LastCellNum 可以用。 它代表是 首列位置 / 末列位置 / 首欄位置 / 末欄位置 但是非常奇異的是,這兩種的取出值卻完全不是這麼一回事 正常來說,以位置來看的話, C# 計算是從 0 開始 因此以上圖 EXCEL來看應該是: FirstRowNum = 0 LastRowNum = 10 FirstCellNum  = 0 LastCellNum  = 10 列(Row) 和 欄(Cell) 和都 各11個 但是,我們實際把它取出來看卻發現詭異事情了 Console.WriteLine("FirstRowNum = " + ws1.FirstRowNum.ToString() + " ,LastRowNum = " + ws1.LastRowNum.ToString()); Console.WriteLine("FirstCellNum = " + ws1.GetRow(0).FirstCellNum.ToString() + " ,LastCellNum = " + ws1.GetRow(0).LastCellNum.ToString()); 結果: 看! LastCellNum 居然是 11  NPOI 有太多小問題真的很想吐槽了 這個問題 去年被發現 ,但是至今尚未改善 如要參照這個屬性一定要非常小心,哪天突然修正好,你的程式可能也要跟著更新與修正了。

關於 NPOI 的 ISheet.RemoveRow 會清除到錯誤的列

圖片
關於 NPOI 套件裏面的 ISheet.RemoveRow 會移除到錯誤的列 的問題 如上圖,我使用如下指令: // 移除最末行 ws1.RemoveRow(ws1.GetRow(10)); 正確來說,它應該會移除第11行的 統計列,但是卻把第10列移除了? ISheet.GetRow 的陣列是從 0 開始的。 如果你用 // 移除第一行 ws1.RemoveRow(ws1.GetRow(0)); 則甚麼事都不會發生,也就是RemoveRow處理的位置是錯誤的。 這個問題好像 在 2016年就有人提出 了,到現在還沒改善.... 使用上還是要小心

C# 使用NPOI 把資料寫到excel檔案(xlsx)

圖片
利用 NPOI 套件產生如上圖的內容到一個excel檔案 本案例 C# 為 .Net 4.5 ,NPOI 為 2.5.1 版 程式碼如下: // 樣式元件 DefXSSFstyle style = new DefXSSFstyle(); IWorkbook wb = new XSSFWorkbook(); // 建立分頁賦予分頁名稱 ISheet ws1 = wb.CreateSheet("統計表"); // 建立數字陣列 10 X 10 for(int i = 1; i<= 10; i++) {     IRow row0 = ws1.CreateRow(i - 1);     for (int j = 1; j <= 10; j++)     {         ICell cell0 = row0.CreateCell(j - 1);         cell0.SetCellValue(((i - 1) * 10) + j);     } } // 建立合計 ASCIIEncoding aSCII = new ASCIIEncoding(); XSSFCellStyle cssf = style.Field09(wb); IRow subRow = ws1.CreateRow(ws1.LastRowNum + 1); for(int k = 1; k <= 10; k++) {     // 設定公式     string headChar = aSCII.GetString(new byte[] { (byte)(64 + k) });     ICell subCell = subRow.CreateCell(k - 1);     subCell.SetCellFormula("SUM(" + headChar + "1:" + headChar + ws1.GetRow(0).LastCellNum.ToString() + ")");     // 加入樣式     subCell.CellStyle = cssf; } // 儲存 string saveFile = savePath + "\\NPOI_RES.xlsx"; //

如何在網頁中呼叫windows本地執行程式 How to run windows application (.exe) in HTML

圖片
有時候我們希望在網頁上開啟本地端的應用程式,但是受限於安全性的關係,通常流覽器都不允許執些開啟本地『執行程式』 在 IE 底下,其實可以透過 ActiveXObject 內建物件建立起 wscript.shell 介面,利用此介面來呼叫本地端程式(其實不一定是程式,已註冊文件類型都可以透過 wscript shell 來開啟。 常見方法如下: <html> <head> <script language="javascript"> function Run(strPath) { var objShell = new ActiveXObject("wscript.shell"); objShell.exec(strPath); objShell = null; } </script> </head> <body> <h1>Call target file : D:\Apps\procexp.exe</h1> <BUTTON class=button onclick="Run('D:\Apps\procexp.exe')">執行 Procexp</BUTTON> </body> </html> 上面就是利用 wscript.shell 呼叫指定程序 procexp.exe 問題是... 它是 IE Only 而且,受限於IE版本的關係,比較新版的 IE 必須要去作安全設定才能整常使用,相當不實用。 那,是否有其他方式呼叫本地應用程式呢? 有的,那就是使用自定義的協定讓瀏覽器接受,例如:eD2k:// VeryCD://等等 如上圖如果利用自訂義的協定就可以讓瀏覽器向註冊表請求自定義協定的動作 因此,必須自己創建協定(不可以和目前使用的協定名稱相同) 例如我要自定義一個協定名稱叫 ZzTest:// ,接下來作法如下 一、開啟註冊登錄表       使用命令列模式(使用者必須有系統管理權限) 輸入 Regedit ,然後 Enter 二、建立

WPF 的 MVVM 測試

圖片
甚麼是WPF WPF(Windows Presentation Foundation) 簡單的說是一種把UI跟程式碼拆開來做的windows應用程式,早期UI的設計與動作都會和程式碼扯上關聯(因為程式碼寫在UI裡面),導致做美編的人員要動到畫面設計時,還得小心考慮到每個物件裡面的程式碼。而微軟在2006年的.NET Framework 3.0以後,重新去定義Windows APP設計的方向與概念而訂製了 WPF 架構。 我想有在設計android程式的人大概見怪不怪了,畢竟android程式的設計就是如此的,UI跟程式碼本來就是分開在設計的。當然習慣於舊式Coding的程式設計師還是會有點難以適應的,因為它不是『直覺』去設計程式的,而是透過『分析』→『模組化』→『開發設計』這種方式去進行開發的。 雖然WPF也可以用比較傳統方式去開發(把各種程式碼寫在UI的片段下)。 但由於『模組化』才是WPF的精隨 ,所以一開始就栽進 M-V-VM 的環境,對於將來開發會比較有幫助的。 網路上也有不少資料可以參考,我這邊就以我 自己的想法去解釋 ,如一開始的圖片。 Model : 主要負責資料結構 (Data Model:Data Structure)的建立或與資料庫連結的存取(DAL;Data Access Layer)的各類模組化都是由這一層負責處理。 View : 主要負責畫面的設計與成型 ,它是一個 .xaml 的 XML 描述檔案,這個描述檔案描述了畫面個元件如何擺放與屬性等,通常它會搭配一個 .cs 的程式碼檔案,雖然可以把程式碼寫在 .cs 裡面,但為了把運算邏輯分離,所以盡可能不要寫入任何與畫面無關的程式碼,甚至根輸入有關的互動運算邏輯也不應該寫在這裡。 ViewModel : 這個才是View的邏輯核心 ,通常一個View會搭配一個ViewModel,而這個ViewModel負責 View 的資料保存(輸入或是顯示用)與畫面元件的互動或是指令,例如按鈕的行為、輸入資料後的自動動作等等,都是在這個模組去完成。透過 View 與 ViewModel 進行結繫(Biding)的方式,也可以讓 View 接收 ViewModel 傳回來的事件要求。 基本型: 假如我需要一個可以輸入產品名稱、數量、成本 與計算小計的功能。 所