目前分類:電腦玩咖 (97)

瀏覽方式: 標題列表 簡短摘要

程式開發手冊 : 

http://4js.com/online_documentation/fjs-fgl-2.50.01-manual-html/

(直接看重點) http://4js.com/online_documentation/fjs-fgl-2.50.01-manual-html/#c_fgl_section_language_basics.html

 

程式錯誤訊息 : 

http://4js.com/online_documentation/fjs-fgl-2.50.01-manual-html/c_fgl_localization_026.html

 

SQL錯誤訊息 : 

http://4js.com/online_documentation/fjs-fgl-2.50.01-manual-html/c_fgl_odiagads_046.html

http://4js.com/online_documentation/fjs-fgl-2.50.01-manual-html/c_fgl_sql_programming_sqlca.html

 

文章標籤

伊 發表在 痞客邦 留言(0) 人氣()

#string split function
#ignore empty value
#p_arg1: input value1 STRING
#p_arg2: input value2 STRING
#r_arr: return value1 DYNAMIC ARRAY OF STRING
#Example: CALL split(str1, str2, arr1)
#   str1 = 'abc-def--1-2'
#   str2 = '-'
#   arr1.getLength() = 4
#   arr1[1] = abc , arr1[2] = def , arr1[3] = 1 , arr1[4] = 2
FUNCTION split(p_arg1,p_arg2,r_arr)
    DEFINE p_arg1   STRING
    DEFINE p_arg2   STRING
    DEFINE r_arr    DYNAMIC ARRAY OF STRING
    DEFINE l_cnt    INTEGER
    DEFINE l_str    STRING
    DEFINE tok      base.StringTokenizer

    CALL r_arr.clear()
    
    LET tok = base.StringTokenizer.create(p_arg1,p_arg2)
    LET l_cnt = tok.countTokens()
    
    IF cl_null(p_arg2) OR l_cnt <= 0 THEN
        RETURN
    ELSE
        WHILE tok.hasMoreTokens()
            LET l_str = tok.nextToken()
            LET l_str = l_str.trim()
            IF NOT cl_null(l_str) THEN
                CALL r_arr.appendElement()
                LET r_arr[r_arr.getLength()] = l_str
            END IF
        END WHILE
    END IF
END FUNCTION

文章標籤

伊 發表在 痞客邦 留言(0) 人氣()

using System.Runtime.InteropServices;

[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int LCMapString(int locale, int dwMapFlags, string lpSrcStr, int cchSrc,
									  [Out] string lpDestStr, int cchDest);

public static string ToSimplified(string argSource)
{
	var t = new String(' ', argSource.Length);
	LCMapString(LocaleSystemDefault, LcmapSimplifiedChinese, argSource, argSource.Length, t, argSource.Length);
	return t;
}

public static string ToTraditional(string argSource)
{
	var t = new String(' ', argSource.Length);
	LCMapString(LocaleSystemDefault, LcmapTraditionalChinese, argSource, argSource.Length, t, argSource.Length);
	return t;
}

伊 發表在 痞客邦 留言(0) 人氣()

Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook = xlApp.Workbooks.Add(misValue); //Create new Excel
Excel.Worksheet xlWorkSheet= (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); //取第一個Sheet

//指定列高, Object的高度約55像素, 這裡用第3列為範例
((Excel.Range)xlWorkSheet.Rows["3:3", System.Type.Missing]).RowHeight = 55;

//取得位置, 這裡用H3為範例
Excel.Range ColH = xlWorkSheet.get_Range("H3");

//Add OLE Object
xlWorkSheet.Shapes.AddOLEObject(ClassType: Type.Missing
	, Filename: Directory.GetCurrentDirectory() + "\\PDF檔案名稱.pdf"
	, Link: false
	, DisplayAsIcon: true
	, IconFileName: Directory.GetCurrentDirectory() + "\\PDF的Icon檔案名稱.ico"
	, IconIndex: "0"
	, IconLabel: "這裡可以寫字"
	, Left: ColH.Left //放 OLE Object 的位置
	, Top: ColH.Top //放 OLE Object 的位置
	//, Width: 15 //有設定Icon時, Width/Height的設定貌似無效
	//, Height: 15 //有設定Icon時, Width/Height的設定貌似無效
);

//xlWorkSheet.Cells.EntireRow.AutoFit(); //自動列高, 因為有指定列高, 這邊不設定自動
xlWorkSheet.Cells.EntireColumn.AutoFit(); //自動欄寬

//另存新檔
xlWorkBook.SaveAs(@"存檔路徑 \\172.16.0.11\Report\", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);

//關閉
xlWorkBook.Close(true, misValue, misValue);
xlApp.DisplayAlerts = false;
xlApp.Quit();

//釋放
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);


private void releaseObject(object obj)
{
	try
	{
		System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
		obj = null;
	}
	catch (Exception ex)
	{
		obj = null;
		Console.WriteLine("Unable to release the Object " + ex.ToString());
	}
	finally
	{
		GC.Collect();
	}
}
文章標籤

伊 發表在 痞客邦 留言(0) 人氣()

Xml File 內容 :

<?xml version="1.0" standalone="yes"?>
<table1>
    <Name>Alice</Name>
    <Mail>alice@mail.com</Mail>
    <Address>No. 19-1, Industry E. Road  IV, Hsinchu Science Park, Hsinchu 30077, Taiwan</Address>
</table1>

C# 內容 :

定義的Class

public class ClassA
{
    public string Name { get; set; }
    public string Mail { get; set; }
    public string Address { get; set; }
    public string table1_Id { get; set; }
}

轉換程式碼 :

XDocument xDoc = XDocument.Load(XmlFilePath);

IEnumerable<ClassA> table1=
    (from s in xDoc.Descendants("table1")
     select new ClassA()
     {
         Name = s.Element("Name") != null ? s.Element("Name").Value : null,
         Mail = s.Element("Mail") != null ? s.Element("Mail").Value : null,
         Address = s.Element("Address") != null ? s.Element("Address").Value : null,
     }).ToList();

 

結果 :

XmlToClassList.png

伊 發表在 痞客邦 留言(0) 人氣()

功能說明 : 避免程式被不小心關閉(按右上角的[X]會縮小, 不會關閉), 不要佔用下方工具列, 縮小到系統匣, 縮小時右下角出現提示訊息.

其他功能說明 : 複製指定檔案, 指定來源及目的路徑, 會遞迴往下尋找資料夾, 目的路徑自動複製來源資料夾的結構.

 

config : 指定檔案, 指定來源及目的路徑.

config1.png

執行畫面

run0.png

按[X]縮小到系統匣.

run1.png

要關閉程式需在系統匣圖示按右鍵, 點[Exit]離開.

run2.png

 

1. 先拉Layout

Layout.png

NotifyIcon : notifyIcon1 系統匣圖示

    *Text一定要設定, 否則縮小到系統匣會看不到. 指定系統匣用的選單.

    notifyIcon1-1.png

ContextMenuStrip : contextMenuStrip1 系統匣選單

    contextMenuStrip1.png

TextBox : textBox1 用來顯示訊息

    textBox1.png

BackgroundWorker : backgroundWorker1 使用背景作業複製檔案, 避免視窗凍結

    *設定 : 可以即時回報訊息, 可以取消背景作業.

    backgroundWorker1-1.png

Timer : timer1 計時器, 才能每隔一段時間執行檔案複製

    timer1-1.png

 

2. 用到的事件

NotifyIcon : notifyIcon1 系統匣圖示

    *單擊 跟 雙擊 圖示, 都可開啟畫面.

    notifyIcon1-2.png

    notifyIcon1-3.png

ToolStripMenuItem : exitToolStripMenuItem 系統匣選單項目

    *因為按[X]不能關閉程式, 所以系統匣提供選單[Exit]讓使用者關閉程式.

    exitToolStripMenuItem3.png

    exitToolStripMenuItem4.png

BackgroundWorker : backgroundWorker1 背景作業

    *指定各個背景作業事件, 因為要能夠回報訊息, 所以有宣告一個全域變數msg存訊息.

    *DoWork裡面不能變動到外部元件(例如寫 TextBox.Text="xxx" 這樣是不行的).

    backgroundWorker1-2.png

    backgroundWorker1-3.png

    backgroundWorker1-4.png

    backgroundWorker1-5.png

Timer : timer1 計時器

    timer1-2.png

    timer1-3.png

Form : 

    *攔截關閉事件, 判斷是要關閉還是要最小化到系統匣.

    *這裡是用 this.WindowState != FormWindowState.Minimized 來判斷. 當視窗不是最小化的時候, 就取消關閉Form事件, 并顯示系統匣圖示.

    Form.png

    FormClosing.png

Others :

    宣告一個全域變數msg存訊息.

    Start.png

    ShowForm.png

    GetFilePathList1.png

    CreatePath1.png

    todo1.png

    todo2.png

 

伊 發表在 痞客邦 留言(0) 人氣()

參考:http://no2don.blogspot.com/2013/02/c-nopi-excel-xls.html

下載NPOI的dll,放到專案 (共五個dll)

using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;

//建立 Workbook
XSSFWorkbook wb = new XSSFWorkbook();

//建立一個叫做"Sheet1"的 Sheet
XSSFSheet st = (XSSFSheet)wb.CreateSheet("Sheet1");

//生成一個新Row (第一列:0, 第二列:1, ...類推)
int row_index = 0;
st.CreateRow(row_index);
//生成這個Row的Cell, 且放值進去 (第一格:0, 第二格:1, ...類推)
st.GetRow(row_index).CreateCell(0, CellType.String).SetCellValue("內容值"); //A1
st.GetRow(row_index).CreateCell(1, CellType.String).SetCellValue("內容值"); //B1

//再生成一個新Row
st.CreateRow(++row_index);
//生成這個Row的Cell, 且放值進去
st.GetRow(row_index).CreateCell(0, CellType.String).SetCellValue("內容值"); //A2
st.GetRow(row_index).CreateCell(1, CellType.String).SetCellValue("內容值"); //B2

//寫入
var file = new FileStream("檔案路徑\\檔案名稱.xlsx", FileMode.Create);
wb.Write(file);
file.Close();

//關閉 Workbook
wb = null;

伊 發表在 痞客邦 留言(0) 人氣()

工作上突然有一個遞迴的需求

需求並不複雜, 用程式就能簡簡單單的寫完

但是SQL語法非常不熟練的我, 突然想說 來練練SQL語法好了 (加上懶得再改程式...)

所以就來研究了一下SQL的遞迴寫法

 

<範例>

有一個資料表: [員工資料表]

欄位很簡單: [主管], [員工]

[主管]欄位是NULL的[員工], 代表沒有人管他, 就是大主管的意思

需求是: 當輸入一個員工姓名, 要把該員工下面所有階層的員工都Show出來

 

SQL語法:

WITH [員工資料表new] AS (
 --找出 [主管] 為 某人 或 NULL 的資料當作 依據
 SELECT [主管], [員工]
 FROM [員工資料表]
 WHERE [主管] = '郭董' --NULL
 
 UNION ALL
 
 --之後以 上面查出的結果 為依據遞迴查詢
 SELECT e.[主管], e.[員工]
 FROM [員工資料表] e
 INNER JOIN [員工資料表new] ecte ON ecte.[員工] = e.[主管]
)
SELECT *
FROM [員工資料表new]

 

實際上工作的需求:

輸入一成品ID, 帶出該產品所需使用的全部材料.

因為材料本身也可能是成品(Type=A或F), 那就要針對是成品的材料再遞迴找出它的材料是什麼, 依此遞迴下去..

DECLARE @APART nvarchar(20) = 'ABC1234567890'

;WITH [MY_BOM] AS (

SELECT b.[APart]
    , b.[Part]
    , p.[Type]
FROM [BOM] b
INNER JOIN [Material] p ON b.[Part] = p.[Part]
WHERE b.[APart]=@APART 

UNION ALL

SELECT bom.[APart]
    , bom.[Part]
    , part.[Type]
FROM [BOM] bom
INNER JOIN [Material] part ON bom.[Part] = part.[Part]
INNER JOIN [MY_BOM] ecte ON ecte.[Part] = bom.[APart] AND (ecte.[Type]='A' OR ecte.[Type]='F')
)
SELECT * FROM [MY_BOM] WHERE [Type]!='A' AND [Type]!='F';

 

伊 發表在 痞客邦 留言(0) 人氣()





















伊 發表在 痞客邦 留言(0) 人氣()

本文轉貼自 : http://bigone2000.pixnet.net/blog/post/56194164-%E4%B8%80%E4%BA%9B%E5%B8%B8%E8%A6%8B%E7%9A%84sql%E6%95%88%E8%83%BD%E5%95%8F%E9%A1%8C

1.  對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。

2.  應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
   select id from t where num is null
   可以在num上設置預設值0,確保表中num列沒有null值,然後這樣查詢:
   select id from t where num=0

3.  應儘量避免在 where 子句中使用!=或<>操作符,否則將使引擎放棄使用索引而進行全表掃描。

4.  應儘量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
     select id from t where num=10 or num=20
     可以這樣查詢:
     select id from t where num=10
     union all
     select id from t where num=20

5.  in 和 not in 也要慎用,否則會導致全表掃描,如:
     select id from t where num in(1,2,3)
     對於連續的數值,能用 between 就不要用 in 了:
     select id from t where num between 1 and 3

6.  下面的查詢也將導致全表掃描:
      select id from t where name like 'abc' 
      若要提高效率,可以考慮全文檢索。

7.  應儘量避免在 where 子句中對欄位進行運算式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
     select id from t where num/2=100
     應改為:  
     select id from t where num=100*2

8.  應儘量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
     select id from t where substring(name,1,3)='abc'--name以abc開頭的id
     select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id應改為:
     select id from t where name like 'abc'
     select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

9.  不要在 where 子句中的“=”左邊進行函數、算術運算或其他運算式運算,否則系統將可能無法正確使用索引。

10.  在使用索引欄位作為條件時,如果該索引是複合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,且應盡可能的讓欄位順序與索引順序一致。

11.  很多時候用 exists 代替 in 是一個好的選擇:
       select num from a where num in(select num from b) 
       用下面的語句替換:
       select num from a where exists(select 1 from b where num=a.num)

12.  並不是所有索引對查詢都有效,SQL是根據表中資料來進行查詢優化的,當索引列有大量資料重複時,SQL查詢可能不會去利用索引,如一表中有欄位sex,male、female幾乎各一半,那麼
      即使在sex上建了索引也對查詢效率起不了作用。

13.  索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,
      視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。

14.  應盡可能的避免更新 clustered 索引資料列,因為 clustered 索引資料列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應
      用系統需要頻繁更新 clustered 索引資料列,那麼需要考慮是否應將該索引建為 clustered 索引。

15.  儘量使用數字型欄位,若只含數值資訊的欄位儘量不要設計為字元型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字串中每一個字元,而
      對於數字型而言只需要比較一次就夠了。

16.  盡可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長欄位存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的欄位內搜索效率顯然要高些。

17.  盡量不要用 select * from t ,用具體的欄位列表代替“*”,不要返回用不到的任何欄位。

伊 發表在 痞客邦 留言(0) 人氣()

SELECT * FROM table WHERE Column LIKE '%test%'

SELECT * FROM table WHERE Contains(Column, "test")>0

伊 發表在 痞客邦 留言(0) 人氣()

當我們希望A表格裡面的aa欄位有值時,就比對B表格的aa欄位要與A表格的aa欄位相符才顯示B的資料;
若A表格的aa欄位沒有值,就不管B表格的aa欄位是否相符。
可用以下的方式:

SELECT *
FROM A
	INNER JOIN B ON A.id=B.id 
	AND (  
			( (A.aa IS NULL OR A.aa = '')   -- IF 表格A的aa欄位是NULL或空值...
				AND B.bb='條件1')
		OR 
			( (A.aa IS NOT NULL)   --ELSE 表格A的aa欄位是其他...
				AND A.aa=B.aa 
				AND B.bb='條件2'))
WHERE ...

伊 發表在 痞客邦 留言(0) 人氣()


var fso = new ActiveXObject("Scripting.FileSystemObject");

var SavePath = "C:\\SaveTest2"; //存檔路徑
var FromPath = "C:\\SaveTest1"; //來源路徑

//檢查資料夾是否存在
if (!fso.FolderExists(FromPath))
fso.CreateFolder(FromPath); //不存在則Create

//建立測試資料
var a = fso.CreateTextFile(FromPath + "\\testfile.txt", true);
a.WriteLine("This is a test.");
a.Close();

//檢查資料夾是否存在
if (!fso.FolderExists(SavePath))
fso.CreateFolder(SavePath); //不存在則Create
else
fso.DeleteFile(SavePath + "\\*.*"); //存在則刪除裡面所有檔案

fso.CopyFile(FromPath + "\\*.*", SavePath + "\\"); //複製A資料夾所有檔案到B資料夾

伊 發表在 痞客邦 留言(0) 人氣()

方法1.(測試不可行,不知道原因)
try
{
    dynamic shell = AutomationFactory.CreateObject("WScript.shell");
    shell.Run(@"C:\Windows\system32\mspaint.exe"); //執行檔路徑
}
catch (Exception ex)
{
    Console.Write(ex.Message);
}


方法2.(測試可行)

(步驟1) .aspx內,寫Javascript,使用ActiveX去開啟Client端的檔案。


(步驟2) .cs內,呼叫html的Javascript Function並帶入路徑參數。
//第一個參數:Javascript Function Name, 第二個參數: Javascript Function的參數.
HtmlPage.Window.Invoke("runEXE", @"C:\Windows\system32\mspaint.exe");


方法2等於還是借助Javascript的ActiveXObject去實現使用者需求。不是Silverlight的功能,也不是.NET的功能。

伊 發表在 痞客邦 留言(1) 人氣()

RIGHT(filepath, CHARINDEX('\',REVERSE(filepath))-1)

伊 發表在 痞客邦 留言(0) 人氣()

ASP.NET (Web Page) 是不能使用建立網路磁碟機連線功能的

但是可以支援UNC路徑,去Access網路上分享的資料夾

路徑格式:\\IP Address or 電腦名稱\資料夾名稱\檔案名稱

因為工作上有需要使用網頁來複製網路上的電腦的檔案到本機資料夾內

就用以前做Win Form時已經寫好的Function來連線網路磁碟機

卻發生無法存取的錯誤

上網查了一下,有文章指示可以直接用UNC路徑

實際寫Web Page測試,確定可以存取

以上資訊分享給有使用到的人~

伊 發表在 痞客邦 留言(0) 人氣()

//宣告
List<string> Items = new List<string>();

//塞值
Items.Add("ABC");
Items.Add("DEF");
Items.Add("GIH");

//傳給另一個變數
List<string> ItemsBackup = new List<string>();
ItemsBackup = Items.ToArray();

//自訂List
public class myListItem
{
    public string Name { get; set; }
    public int Age { get; set; }       
}
//宣告
List<myListItem> Items = new List<myListItem>();
//塞值
Items.Add(new myListItem()
{
	Name = "Annie",
	Age = 18,
});

伊 發表在 痞客邦 留言(0) 人氣()

查看windows xp及windows 7的開機記錄

利用windows內建的事件檢視器即可查看開關機記錄。

1.開啟事件檢視器
方法一:開始>執行>eventvwr.exe
方法二:在[我的電腦]按右鍵>[管理],在[系統工具]裡可看到[事件檢視器]

2.[事件檢視器]的「系統」選項紀錄了開關機日期時間
在windows xp中,開機的代碼是6005,關機是6006。
在windows 7中,開機的代碼是12,關機是13。

其他代碼的意義可到 www.eventid.net 網站查詢

伊 發表在 痞客邦 留言(0) 人氣()

C#

void Button1Click(object sender, EventArgs e)
{
	//用東方神起的中文版歌詞當範例@@,剛好寫程式時在聽 ...
	//剛好也可以示範一下字串在程式碼中如何斷行 ...
	//還有換行符號 ...
	string str = 
		"一次 一次也沒有 直到最後也沒有對我敞開心扉\r\n" + 
		"我就想面壁而立的心情 你知道嗎\r\n" + 
		"\r\n" + 
		"雖然在身邊卻變得更加孤獨\r\n" + 
		"tonight tonight tonight\r\n" + 
		"\r\n" + 
		"雖然等待了你 但不會這樣了\r\n" + 
		"現在我要離開你\r\n" + 
		"\r\n" + 
		"不要走 我一句都不會說 你這個傻瓜\r\n" + 
		"我為什麼只看著你這個傻瓜 那麼不爭氣的你\r\n" + 
		"\r\n" + 
		"baby catch me catch me catch me girl tonight\r\n" + 
		"在我離開你之前(I'm serious I'm serious)\r\n" + 
		"\r\n" + 
		"抓著我不讓走 哭著打我 如果告訴我理由\r\n" + 
		"(I'm serious I'm serious)\r\n" + 
		"\r\n" + 
		"我不知道 我還不知道我在你心裡面到底有多深\r\n" + 
		"我很想知道 在我疲憊放棄前\r\n" + 
		"\r\n" + 
		"告訴我吧 告訴我吧 回答我\r\n" + 
		"\r\n" + 
		"時間就這麼全花在你身上 現在 在那個位置上\r\n" + 
		"不要送別我 你會後悔的 不要犯蠢\r\n" + 
		"\r\n" + 
		"不要走 我一句都不會說 你這個傻瓜\r\n" + 
		"我為什麼只看著你這個傻瓜 那麼不爭氣的你\r\n" + 
		"\r\n" + 
		"之前你對於我來說\r\n" + 
		"我記得那只被你充滿的心情 真的很幸福\r\n" + 
		"\r\n" + 
		"會像我這樣等帶著你的人 no 你不要忘記了\r\n" + 
		"\r\n" + 
		"現在或未來都不要離開我 對我說這樣的話吧\r\n" + 
		"太遲鈍了 直到你整理好心情之時\r\n" + 
		"\r\n" + 
		"我都會只看著你 我到底是為什麼\r\n" + 
		"希望你來哀求我 我會等你的\r\n" + 
		"\r\n" + 
		"現在或未來都不要離開我 對我說這樣的話吧\r\n" + 
		"傻瓜 我為什麼會愛你\r\n" + 
		"\r\n" + 
		"只愛你這到底為什麼\r\n" + 
		"\r\n" + 
		"不要走 我一句都不會說 你這個傻瓜\r\n" + 
		"我為什麼只看著你這個傻瓜 那麼不爭氣的你\r\n" + 
		"\r\n" + 
		"baby catch me catch me catch me girl tonight\r\n" + 
		"在我離開你之前(I'm serious I'm serious)\r\n" + 
		"\r\n" + 
		"抓著我不讓走 哭著打我 如果告訴我理由\r\n" + 
		"(I'm serious I'm serious)\r\n" + 
		"\r\n" + 
		"chtch me if you wanna";
	
	StringDelayPrint(str);
}

void StringDelayPrint(string str)
{
	if(timer1.Enabled == true) return; //如果已經在顯示中,不要繼續重複動作
	txtPrint.Text = ""; //清除顯示用的TextBox
	txtPrintBuffer.Text = str; //將要顯示的字串存到暫存TextBox中
	timer1.Interval = 300; //設定每字顯示的間隔時間,毫秒為單位
	timer1.Enabled = true; //將Timer元件啟動
}

void Timer1Tick(object sender, EventArgs e)
{
	string str = txtPrintBuffer.Text; //取出欲顯示的字串,string做處理比較方便
	txtPrint.Text = txtPrint.Text + str[txtPrint.TextLength]; //逐字顯示
	
	//以下三行是讓TextBox自動捲到最下面
	txtPrint.SelectionStart = txtPrint.Text.Length;*
	txtPrint.ScrollToCaret(); 
	txtPrint.Refresh();
	
	//如果已經顯示字串最尾,就停止Timer
	if(txtPrint.TextLength == str.Length) timer1.Enabled = false;
}

伊 發表在 痞客邦 留言(0) 人氣()

    public partial class MainForm : Form
    {
        System.IO.Ports.SerialPort serialport = new System.IO.Ports.SerialPort();//宣告連接埠
        Boolean light = false, serialportopen = false;
        
        public MainForm()
        {
            InitializeComponent();
            
            foreach(string com in System.IO.Ports.SerialPort.GetPortNames())//取得所有可用的連接埠
            {
                cbPortName.Items.Add(com);
            }
            if (cbPortName.Items.Count > 0)
                cbPortName.SelectedIndex = 0;
            
            cbCmd.Items.Add("0-讀取");
            cbCmd.Items.Add("1-寫入");
            cbCmd.Items.Add("7-強制ON");
            cbCmd.Items.Add("8-強制OFF");
            if(cbCmd.Items.Count>1)
                cbCmd.SelectedIndex=0;
        }
        
        void Button1Click(object sender, EventArgs e)
        {
            if (serialportopen == false && !serialport.IsOpen)
            {
                try
                {
                    //設定連接埠
                    serialport.PortName = cbPortName.Text;//連線埠
                    serialport.BaudRate = 9600;//鮑率
                    serialport.DataBits = 7;//數據位元
                    serialport.Parity = System.IO.Ports.Parity.Even;//偶同位
                    serialport.StopBits = System.IO.Ports.StopBits.One;//停止位元
                    serialport.Encoding = Encoding.Default;//傳輸編碼方式
                    serialport.Open();
                    serialportopen = true;
                    button2.Enabled = true;
                    txtSTX.Enabled = true;
                    if (this.backgroundWorker1.IsBusy != true)
                    {
                        this.backgroundWorker1.WorkerReportsProgress = true;
                        this.backgroundWorker1.RunWorkerAsync();
                    }
                    button1.Text = "中斷";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            else if (serialportopen == true && serialport.IsOpen)
            {
                try
                {
                    serialport.Close();
                    if (!serialport.IsOpen)
                    {
                        serialportopen = false;
                        button2.Enabled = false;
                        txtSTX.Enabled = false;
                        this.backgroundWorker1.WorkerReportsProgress = false;
                        this.backgroundWorker1.CancelAsync();
                        this.backgroundWorker1.Dispose();
                        label3.ForeColor = Color.Red;
                        button1.Text = "連線";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }
        

        private void Button2Click(object sender, EventArgs e)
        {
            try
            {
                string str = "";
                //STX Cmd Addrs Bytes Data ETX SUM
                //str = (Char)2 + "70008" + (Char)3 + "02";//M0
                //str = (Char)2 + "70108" + (Char)3 + "03";//M1
                //str = (Char)2 + "70208" + (Char)3 + "04";//M2
                //str = (Char)2 + "70308" + (Char)3 + "05";//M3
                str = (Char)2 + txtCmd.Text + txtAddrs.Text + txtBytes.Text + txtData.Text + (Char)3 + txtSum.Text;
                serialport.Write(str);
                AddText(MsgType.Error, "傳送:" + str + "\r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
        {
            if(e.KeyChar==(Char)13)
            {
                Button2Click(sender, e);
            }
        }

        private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
        {
            for (; ; )
            {
                if (backgroundWorker1.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    try
                    {
                        backgroundWorker1.ReportProgress(0);
                        System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception)
                    {
                        e.Cancel = true;
                        break;
                    }
                }
            }
        }

        private void BackgroundWorker1ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                if (serialport.BytesToRead != 0)
                {
                    label2.Text = "緩衝區:" + serialport.BytesToRead.ToString();
                    AddText(MsgType.System, "接收:" + serialport.ReadExisting() + "\r\n");
                    serialport.DiscardInBuffer();
                }
            }
            catch(Exception)
            {}
        }

        private void AddText(MsgType msgtype, string msg)
        {
            richTextBox1.Invoke(new EventHandler(delegate
            {
                richTextBox1.SelectedText = string.Empty;
                richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                richTextBox1.SelectionColor = MsgTypeColor[(int)msgtype];
                richTextBox1.AppendText(msg);
                richTextBox1.ScrollToCaret();
            }));
        }
        
        //FX2N CheckSum,取 CMD、ADDR、DATA、ETX 各字元的 ASCII碼 16進位表示法 加總,然後取最後兩個字元。
        private string CheckSum()
        {
            //宣告:int為整數、string為字符串
            int sum = 0;
            string checkstring = "";
            string checksum = "";
        
            //通訊格式中的英文字符必須為大寫(a~f),故先行將text所輸入之傳送數據,經由程序自動轉換為大寫字母,然後加上結束碼etx:chr(3),形成一字符串checkstring
            checkstring = (String)txtCmd.Text + txtAddrs.Text + txtBytes.Text + txtData.Text + (Char)3;
        
            // for屬於重複結構中之計數循環,指令pc在一定的次數內,重複的執行某一敘述區段,亦即取出checkstring字符串中每一個字符,並累加每一個字符的ascii碼,而得出一整數sum。
            for (int i = 0; i < checkstring.Length; i++) {
                sum = sum + Convert.ToInt32(checkstring[i]);
            }
        
            //將10進制整數sum轉換為16進制,並取其右邊二位數,即為所求檢查碼。
            checksum = String.Format("{0:X}", sum);
            checksum.PadLeft(2,'0');
            checksum = checksum.Substring(checksum.Length - 2, 2);
            
            return checksum;
        }
        
        void Button3Click(object sender, EventArgs e)
        {
            string sum = CheckSum();
            txtSum.Text = sum;
        }
        
        void CbCmdSelectedIndexChanged(object sender, EventArgs e)
        {
            string cmd = cbCmd.Text.Split('-')[0];
            txtCmd.Text = cmd;
        }
        
        void SendStr(string str)
        {
            try
            {
                //STX Cmd Addrs Bytes Data ETX SUM
                //str = (Char)2 + "70008" + (Char)3 + "02";//M0
                //str = (Char)2 + "70108" + (Char)3 + "03";//M1
                //str = (Char)2 + "70208" + (Char)3 + "04";//M2
                //str = (Char)2 + "70308" + (Char)3 + "05";//M3
                serialport.Write(str);
                AddText(MsgType.Error, "傳送:" + str + "\r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }

伊 發表在 痞客邦 留言(2) 人氣()

1 2345