手邊有一張速查表(Cheat Sheets)是件很方便的事

我個人有習慣收集一些網路上別人整理的速查表,因為程式開發的細節真的太多了,要能全部背起來不太可能,也沒什麼意義,甚至於有人說程式設計就是一件查詢、複製、貼上的工作而已。對我來說,寫程式首重觀念與經驗,有了完整而正確的觀念,就算記不得要怎麼寫,查詢一下就馬上能寫了;而有了經驗,對於一些難解的 Bug 自然能夠迅速解開。

所以當我在開發網站時只要開啟速查表文件,有時後看表提醒一下用法,馬上就可以解決問題。例如:像我之前是寫 PHP 好多年之後才突然轉換到 C# / ASP.NET 的,而當初我剛學 .NET 時,對 .NET 的 String.Format 十分感冒,因為不會用,且當時輸入的範例又寫的很不清楚,有時後為了輸出一個 NT$ 1,000,000.00 這樣的格式都要寫好久,真的很氣人。直到有一天在 John Sheehan 這位仁兄的網站看到 .NET Format String Quick Reference 這份速查表文件,因為講解的仔細又有範例,讓我一下子就掌握所有 String.Format 的用法,而這份文件也是我最常用的速查表之一。

以下是我這陣子累積整理的 Cheat Sheets 相關連結,各位如果有覺得不錯的也可以推薦給我,我再放上來:

C# / .NET / LINQ 相關

Visual Studio 相關

ASP.NET 相關

SQL Server 相關

Subversion 相關

Reqular Expression 相關

CSS 相關

HTML / XML / RGB 相關

ASP / VBScript 相關

PHP 相關

JavaScript 相關

系統管理

  

此文章由 will 發表於 2008/11/27 下午 03:23:08

永久連結 | 評論 (3) | 此文章的RSSRSS comment feed |

分類: .Net | ASP.NET | C# | CSS | JavaScript | LINQ | PHP | Security | SQL Server | Subversion | VBA | Visual Basic | Visual Studio | Web

標籤: , , , , , , , , , , , , , , ,

收藏:

啟動 ASP.NET 偵錯模式的另一種比按下 F5 還快的方式

大部分人在測試 ASP.NET 程式時,大多按下 F5 (開始偵錯)(Start Debugging) 進入 ASP.NET 偵錯模式,不過我個人覺得這個程序非常的慢,所以大多不會直接按下 F5,而是先用 Ctrl + F5 直接看執行的結果,速度會快很多,因為大部分時候只是看執行結果,並沒有設定中斷點,無須進入偵錯模式。我之前曾經提過兩篇(這篇 & 這篇)在 Visual Studio 中關於 Attach to Process 的文章,所以當我需要除錯時才會利用 Attach to Process 將 WebDev.WebServer.EXE 程序附加上去,就可以進入偵錯模式了。

附加的步驟十分簡單,只需兩個步驟:

VS2008 -> Tools -> Attach to Process

Attach to Process -> WebDev.WebServer.EXE

不過,雖然只有兩個步驟,但我還是覺得每次都這麼做太麻煩,所以研究出透過 巨集(Macro) + 快速鍵繫結 的方式,可以快速啟動 ASP.NET 偵錯。

建立巨集函數

1. 先按下 Alt + F8 開啟 Macro Explorer

2. 新增一個新的巨集模組(Module)

 新增一個新的巨集模組(Module)

3. 編輯剛剛新增的巨集模組

編輯剛剛新增的巨集模組

4. 將以下巨集貼到 Public Module Module1 與 End Module 之間,並按下 Ctrl + S 存檔

Sub 附加偵錯程序()
    Try
        Dim m_DBG2 As EnvDTE80.Debugger2 = DTE.Debugger
        Dim m_Transport As EnvDTE80.Transport = m_DBG2.Transports.Item("Default")
        Dim m_DbgEngine(1) As EnvDTE80.Engine
        m_DbgEngine(0) = m_Transport.Engines.Item("Managed")
        Dim m_Process2 As EnvDTE80.Process2
        Try
            m_Process2 = m_DBG2.GetProcesses(m_Transport, "").Item("WebDev.WebServer.EXE")
        Catch ex As Exception
            MsgBox("您尚未啟動網站,建議先按下 Ctrl + F5 啟動網站")
            Return
        End Try
        m_Process2.Attach2(m_DbgEngine)
    Catch ex As System.Exception
        MsgBox(ex.Message)
    End Try
End Sub

5. 之後會在 Macro Explorer 看到剛剛定義的巨集

在 Macro Explorer 會看到剛剛定義的巨集

設定快速鍵繫結巨集執行

1. 開啟 Tools 選單 / Options,並找到 Environment / Keyboard 項目

2. 先在 Show commands containing 輸入「關鍵字」,例如輸入:附加

3. 找到你的巨集後,在底下的 Press shortcut keys 輸入「快速鍵」,並按下 Assign 即可(如下圖示)

開啟 Tools 選單 / Options,並找到 Environment / Keyboard 項目, 先在 Show commands containing 輸入「關鍵字」,例如輸入:附加, 找到你的巨集後,在底下的 Press shortcut keys 輸入「快速鍵」,並按下 Assign 即可

註:Visual Studio 中的快速鍵真是爆多的,要找到一個還沒用的還真難,我好不容易找到 Alt + ` 快速鍵

之後你就只要按下 Alt + ` 即可快速啟動 ASP.NET 偵錯程序了!

註:Visual Studio 內建關閉偵錯模式的快速鍵是 Shift + F5

  

此文章由 will 發表於 2008/11/6 上午 11:38:31

永久連結 | 評論 (11) | 此文章的RSSRSS comment feed |

分類: ASP.NET | Tips | VBA | Visual Studio

標籤: , , ,

收藏:

透過 OleDb 精準讀入 Excel 檔的方法

之前因為有個案子要做 Excel 匯入的功能,需要讓客戶先下載匯入檔案範本,然後讓客戶上傳 Excel 檔 ( *.xls ),再透過 C# 讀取資料後存入資料庫,我是採用 OleDb 的方式在 Server 端開啟檔案並將資料讀出,不過卻遇到了幾個難解的問題,其中最討厭的問題就是透過 OleDb 載入資料時,它都會自動判斷 Excel 中每個欄位的型別,假設工作表中的第三欄的前 8 列的值是「數字」,而第 9 列的「文字」的話,當讀取到第 3 欄第 9 列的時候,該儲存格的欄位值就會是 Null,可能會引發程式執行錯誤(因為你會預期有資料)。

這又是一個不認真讀書、找資料的典範啦,我當初在寫的時候是有找到一些資料,不過卻沒認真看完,網路上隨便抓一段 Sample Code 就開始寫了(我相信大部分的人都這樣),而當遇到問題的時候就開始直覺的反應 "這怎麼可能" 、 "又是微軟的 Bug" 、 "天阿, OleDb 真難用" 等等(髒話的部分已經刪除),等在內心抱怨完之後(大約兩秒)就開始發揮創意想解決方案(這也是最好玩的部分),當然沒有無法解決的問題,我還是想到了一個當初自己覺得還蠻不錯的方法。(現在覺得很爛,勿學)

為了確保讀出的資料全部都是「文字」,我自己手動建立了一個 Typed DataSet,並將所有欄位都設定成 string,然後透過 OldeDb 將 Excel 資料讀出後存入 Typed DataTable,但這樣還是會發生資料為 Null 的情形,所以我又修改 Excel 匯入檔案範本加入一段 VBA 程式碼,讓客戶在 Excel 中輸入完文字後按下某個按鈕,強迫將所有欄位格式先轉成文字,反正就是一整個囉唆啦。

不過為了寫出這篇文章,我把之前找的文章仔細的看過一遍了,才知道我之前的 "解決方案" 實在是太蠢了,以下是比較聰明的解法。

一般來說,透過 OleDb 載入 Excel 檔案時,設定的連線參數如下:

string _connstr = "Provider=Microsoft.Jet.OLEDB.4.0;" + 
    "Data Source=C:\\MyExcel.xls;" + 
    "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";

其中,最關鍵的部分就是在 Extended Properties 的地方,我逐一介紹:

  1. Excel 8.0

    Excel 8.0 是 Office 97 的 Excel 格式,這個格式從 Excel 97 ~ Excel 2003 都相容,如果你在 Excel 中使用「另存新檔」的話,必須要選取這個檔案類型儲存,才能正確用 OleDb 正確開啟,如下圖示:
    Excel 另存新檔所儲存的類型 
  2. HDR ( HeaDer Row )

    若指定值為 Yes,代表 Excel 檔中的工作表第一列是欄位名稱
    若指定值為 No,代表 Excel 檔中的工作表第一列就是資料了,沒有欄位名稱
  3. IMEX ( IMport EXport mode )

    IMEX 有三種模式,分別讀寫行為也不同,容後再述:
    0 is Export mode
    1 is Import mode
    2 is Linked mode (full update capabilities)

我想最需要說明的就是 IMEX 參數了,因為不同的模式代表著不同的讀寫行為:

  • 當 IMEX=0 時為「匯出模式」,這個模式開啟的 Excel 檔案只能用來做「寫入」用途。
  • 當 IMEX=1 時為「匯入模式」,這個模式開啟的 Excel 檔案只能用來做「讀取」用途。
  • 當 IMEX=2 時為「連結模式」,這個模式開啟的 Excel 檔案可同時支援「讀取」與「寫入」用途。

所以當我們要開發 Excel 檔案匯入功能時,正確的 IMEX 設定應該是 1 才對,不過就算設定 IMEX=1 還不夠,還有一些需要注意的地方!

你可以開啟 regedit 程式,選取進系統機碼(Registry)的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5\Engines\Excel 位置,這裡有兩個非常重要的設定:

系統機碼(Registry)的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5\Engines\Excel

在 Excel 機碼中 ImportMixedTypes 的預設值為 Text,代表當你讀入 Excel 檔案時若每一列的資料格式不一致的話,Jet Engine 預設會將欄位的資料格式自動轉成文字(Text)格式!

在 Excel 機碼中 TypeGuessRows 的預設值為 8,代表當你讀入 Excel 檔案時若每一列的資料格式不一致的話,Jet Engine 會先讀取前 8 列的資料,用已判斷之後的資料格式是否固定。假設若前 8 列的資料都是「日期」格式,那麼在第 8 列之後的資料 Jet Engine 會自動解析成「日期」格式,但只要遇到有的資料不是「日期」格式時,就會回傳 Null 給 Jet Engine,也就是本篇文章一開始的問題。

我們是提供 Excel 檔案範本給客戶沒錯,但是強大的 Excel 實在太好用了,導致客戶要怎麼用你根本管不著,原本設定好的格式經過客戶複製、剪貼後,格式就大亂了,導致匯入程式就很容易出錯,而最可惡的就是在 Excel 中明明就有資料,而匯入到資料庫之後卻有些資料是空的,這..這..這..太難跟客戶解釋了!(這時候不得不搬出程式設計師最常說的話排行榜)。

要解決這個問題也很容易,只要將 Excel 機碼中 TypeGuessRows 的值改成 0 即可,只是若你匯入的資料量蠻大的話可能會影響資料讀取時的效能,因為 Jet Engine 會將所有資料讀完才會判斷出每個欄位應該用什麼資料格式。

最後提醒,若你的 Excel 檔案有在 Office 中做加密保護的話是無法透過 OleDb 讀取的。

相關連結

  

此文章由 will 發表於 2008/8/5 下午 02:11:17

永久連結 | 評論 (9) | 此文章的RSSRSS comment feed |

分類: .Net | C# | Office | Tips | VBA

標籤: , , ,

收藏:

加速 VBA 對文件的操作速度

我們為了大量更新 Office 文件內容,加速更新速度的方式,就是修改 Application.ScreenUpdating = False

因為你每做一個指令,就會造成畫面更新,如果你的文件有上千頁,速度就會被拖的很慢,所以最快的方式就是先通知 Office 先不要更新畫面,等做完再更新!

 Sub 刪除文件中所有圖片()
 '
 ' 範例:刪除文件中所有圖片
 '
 '
     Application.ScreenUpdating = False
    
     Selection.HomeKey Unit:=wdStory
    
     Selection.Find.ClearFormatting
     With Selection.Find
         .Text = "^g"
         .Replacement.Text = ""
         .Forward = True
         .Wrap = wdFindContinue
         .Format = False
         .MatchCase = False
         .MatchWholeWord = False
         .MatchByte = True
         .MatchWildcards = False
         .MatchSoundsLike = False
         .MatchAllWordForms = False
     End With
    
     While Selection.Find.Execute
         Selection.Delete Unit:=wdCharacter, Count:=1
     Wend
    
     Application.ScreenRefresh
    
     Application.ScreenUpdating = True
    
 End Sub

 

  

此文章由 will 發表於 2007/11/29 下午 11:19:00

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: Office | VBA | Tips

標籤: , ,

收藏:

如何用 VBA 將傳進來的半型數字字串轉成國字大寫

' 將傳進來的半型數字字串轉成國字大寫
' -------------------------------------------
Function 轉國字(s As String) As String
  Dim s1 As String
  Dim s2 As Long
  If s = "" Then 轉國字 = "未輸入金額": Exit Function
  While Left(s, 1) = "0": s = Right(s, Len(s) - 1): Wend
  tmp節名 = "元萬億兆京"
  節數 = (Len(s) - 1) \ 4 + 1
  位數 = 節數 * 4
  s = Right("0000" & s, 位數)
  For i = 節數 To 1 Step -1
    個位名 = Mid(tmp節名, i, 1)
    s1 = Mid(s, ((節數 - i) * 4) + 1, 4)
    zero = ""
    If Left(s1, 1) = "0" Then zero = "零"
    tmp = tmp & zero & 轉四位數(s1) & 個位名
  Next
  If Left(tmp, 1) = "零" Then tmp = Right(tmp, Len(tmp) - 1)
  tmp = Replace(tmp, "零零", "零")
  tmp = Replace(tmp, "零萬", "")
  tmp = Replace(tmp, "零億", "")
  tmp = Replace(tmp, "零元", "元")
  轉國字 = tmp & "整"
End Function

Function 轉四位數(s As String) As String
  If s = "0000" Then 轉四位數 = "零": Exit Function
  While Left(s, 1) = "0": s = Right(s, Len(s) - 1): Wend
  s = StrReverse(s)
  tmp位名 = " 拾佰仟"
  tmp國字 = "零壹貳參肆伍陸柒捌玖"
  For i = 1 To Len(s)
    英數字 = Mid(s, i, 1)
    國數字 = Mid(tmp國字, 英數字 + 1, 1)
    位名 = Mid(tmp位名, i, 1): If 英數字 = "0" Then 位名 = ""
    結果 = 國數字 & 位名 & 結果
  Next
  結果 = Replace(結果, "零零零", "零")
  結果 = Replace(結果, "零零", "零")
  If Right(結果, 1) = "零" Then 結果 = Left(結果, Len(結果) - 1)
  轉四位數 = Trim(結果)
End Function

Private Sub Command1_Click()
  Debug.Print 轉國字("1234567890123")
  Debug.Print 轉國字("10003000")
  Debug.Print 轉國字("1502000")
  Debug.Print 轉國字("10000000000")
  Debug.Print 轉國字("100000000000000")
End Sub


' 將傳進來的英文字串轉成全形英文

Function ChgToAll(Word As String) As String
    Dim WoAll As String
    Dim NewWord As String
    NewWord = ""
    WoAll = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    For i = 1 To Len(Word)
        If Asc(Mid(Word, i, 1)) - 65 >= 0 And Asc(Mid(Word, i, 1)) - 65 <= 25 Then
            NewWord = NewWord + Mid(WoAll, Asc(Mid(Word, i, 1)) - 65 + 1, 1)
        Else
            NewWord = NewWord + Mid(Word, i, 1)
        End If
    Next i

    ChgToAll = NewWord
End Function

  

此文章由 will 發表於 2007/10/29 下午 08:22:00

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: VBA

標籤:

收藏: