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

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

參考: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;

伊 發表在 痞客邦 PIXNET 留言(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';

 

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





















伊 發表在 痞客邦 PIXNET 留言(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 ,用具體的欄位列表代替“*”,不要返回用不到的任何欄位。

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

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

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

伊 發表在 痞客邦 PIXNET 留言(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 ...

伊 發表在 痞客邦 PIXNET 留言(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資料夾

伊 發表在 痞客邦 PIXNET 留言(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的功能。

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

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

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

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

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

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

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

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

卻發生無法存取的錯誤

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

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

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

伊 發表在 痞客邦 PIXNET 留言(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,
});

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

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

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

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

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

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

伊 發表在 痞客邦 PIXNET 留言(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;
}

伊 發表在 痞客邦 PIXNET 留言(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());
            }
        }
    }

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

【通訊】

RS232(PC) 對 RS422(PLC)

宣告RS232Port:
System.IO.Ports.SerialPort sp = new System.IO.Ports.SerialPort();

通訊設定:
1. Port Name (EX. COM1, COM2 ...)
2. 非同步雙向 Baud Rate = 9600
3. 資料7位元 Data Bits = 7
4. 停止位元1個 Stop Bits = System.IO.Ports.StopBits.One
5. 檢查位元為偶同位 Parity = System.IO.Ports.Parity.Even

傳送格式:
STX + Cmd + Address + Bytes + Data + ETX + CheckSum


查資料Y20的元件位址是0510
單一元件通訊命令(起始碼+控制碼+元件位址+結束碼+偵誤碼)
起始碼是ASCII碼02
控制碼強制ON是7,強制OFF是8
元件位址要上下位互換,所以在這裡要輸入1005
結束碼是ASCII碼03PL
偵誤碼是控制碼+元件位址的每個字元轉成ASCII碼數值全部相加,在轉成16進制數值取最後2位
其中ASCII碼02和03是不可見字元,就算輸入螢幕上也是看不到字的
Y20強制ON的字串→(ASCII碼02)71005(ASCII碼03)00→算出的偵誤碼是00
Y20強制OFF的字串→(ASCII碼02)81005(ASCII碼03)01→算出的偵誤碼是01

查資料D112的元件群組位址是10E0
D暫存器的字元寫入命令(起始碼+控制碼+元件群組位址+寫入組數+寫入資料+結束碼+偵誤碼)
起始碼是ASCII碼02
控制碼寫入是1
元件群組位址不用換位所以是10E0
三菱PLC每筆資料是8位元,D暫存器是16位元,所以寫入組數是02組(要輸入16進制數值)
寫入資料是1,換算成16進制字串是0001,寫入資料每8位元1組分成上下位元,上下位元要互換位置,所以在這裡要輸入0100
結束碼是ASCII碼03
偵誤碼是控制碼+元件群組位址+寫入組數+寫入資料的每個字元轉成ASCII碼數值全部相加,在轉成16進制數值取最後2位
D112寫入1的字串→(ASCII碼02)110E0020100(ASCII碼03)2D→算出的偵誤碼是2D


【指令】

[K4M100 的意思]

K1代表連續的4個位址,K4代表4×4個連續位址,也就是16個。

同理,K2是8個連續位址;K3是12個連續位址。

M100是一個位址,K4代表M100到M115這16個位址,不是M100代表16個位址。


[TO 指令]

TO 模組索引 記憶體位址(BFM) 值 傳幾個

※記憶體位址(BFM)編號從0開始,0~31,共32個,每個位址有16bit可用。

例. TO K0 K3 H0000 K1
將H0000傳送到PLC後面順位第1的模組的BFM#3。

如果改成 TO K0 K3 H0000 K2
將H0000傳送到PLC後面順位第1的模組的BFM#3、#4。

另有:
DTO 一次傳輸32bit


[FROM 指令]

FROM 模組索引 記憶體位址(BFM) 存放位址 傳幾個

另有:
DFROM 一次傳輸32bit


[FMOV 指令]

16位元連續執行多點傳送指令

例. FMOV K0 D300 K2
將K0(值0)傳送到D300~D301

另有:
FMOVP 16位元脈衝執行多點傳送指令
DFMOV 32位元連續執行多點傳送指令
DFMOVP 32位元脈衝執行多點傳送指令


[SET/RST 指令]

SET:置位指令,使操作保持ON的指令。
RST:复位指令,使操作保持OFF的指令。

SET指令可用于Y,M和S,RST指令可用于复位Y,M,S,T,C,或将字元件D,V和Z清零。


[ZRST 指令]

重置

例. ZRST M0 M499
將M0~M499的值全部復位


[PLS/PLF 指令]

PLS(Pulse):上升沿微分輸出指令。
PLF:下降沿微分輸出指令。
PLS和PLF指令只能用於輸出繼電器和輔助繼電器(不包括特殊輔助繼電器)。

PLC_PLS_PLF

圖中的M0僅在X0的常開觸點由斷開變為接通(即X0的上升沿)時的一個掃描週期內為ON,M1僅在X0的常開觸點由接通變為斷開(即X0的下降沿)時的_個掃描週期內為ON。
當PLC從RUN到STOP,然後又由STOP進入RUN狀態時,其輸入信號仍然為ON,PLS M0指令將輸出一個脈衝。然而,如果用電池後備(鎖存)的輔助繼電器代替M0,其PLS指令在這種情況下不會輸出脈衝。


[比較指令]
如CMP K100 C30 M0
简单说就是前两个数(100和计数器C30里的数)比较,将>、<、=三个状态输出到三个位!而M0为首地址、依次是M0、M1、M2
K100>C30 M0=1 M1=0 M2=0
K100=C30 M0=0 M1=1 M2=0
K100
[<= Z0 D20] 的意思是: 如果Z0 <= D20成立,则执行后面的程序


[ADD]

ADD D21 D201Z0 D21 意思是 D21 = D21 + D201Z0; Z0是变址寄存器,所以到底加那个D地址由Z0的偏移后得出


[INC/DEC]

逻辑运算指令 INC 加1指令 DEC 减1

比如说定时器设定值就要用INC 加1 指令或 DEC 减1指令来改变寄存器的常数。

INC,INCP,DEC,DECP:16位指令
DINC,DINCP,DDEC,DDECP:32位指令
P是脉冲执行指令

增加指令与减少指令编程方式如下:
INC D10
DEC D10
*D10的值加1,可以为寄存器,T,C或是位元件的组合如K4Y0

假设程序扫描周期为2ms,M0闭合时间为10ms,执行前D10的值为0。下面两段程序的执行结果为:
LD M0
INC D10
D10的值为5

LD M0
INCP D10
D10的值为1

INCP Z1
累加的就是Z1
如Z1第一次为1、执行一次就是2
如果用D0Z1,则Z1=0时,对应D0,执行一次对应D1,再后面依次D2、D3
Z1里面的数据+1,如果这个数据你用在地址上,那就是地址加一
Z是变址寄存器,所以最终改变的是地址


[SUBP 减法指令]

P表示该指令为脉冲指令,只在上升沿时执行1次。下次执行须重新触发

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

object.options.length = 0;

document.getElementById(Id).options.length = 0;

document.getElementByName(Name).options.length = 0;

document.forms[FormName].elements[SelectName].options.length = 0;

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

var curMonthDays = new Date(year,month,0).getDate();

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

這個範例程式,會顯示進度字串到textbox內,textbox會自動捲動到最下方,會顯示進度條(0~100),可讓使用者中斷程序。
VB部分的程式碼我是用網路上C#toVB轉換器轉的,所以不知道有無錯誤,請網友費心試試看囉~

程式元件畫面:
NET背景執行

//C#

//---------設計畫面時的設定---------
this.button1.Text = "開始";
this.button2.Text = "停止";
this.textBox1.Multiline = true; //多行
this.textBox1.ScrollBars = ScrollBars.Vertical; //顯示垂直捲軸
this.backgroundWorker1.WorkerReportsProgress = true; //回報進度
this.backgroundWorker1.WorkerSupportsCancellation = true; //允許中斷
this.timer1.Interval = 1000;
//--------------------------------

string msg; //存放回報訊息
DateTime TimerTick; //計時器時間

private void button1_Click(object sender, EventArgs e)
{
    this.TimerTick = DateTime.Parse("2000/1/1 00:00:00"); //初始時間點
    this.timer1.Start(); //啟動計時器
    this.progressBar1.Visible = true; //顯示進度條
    this.backgroundWorker1.RunWorkerAsync(); //呼叫背景程式
}

private void button2_Click(object sender, EventArgs e)
{
    this.backgroundWorker1.CancelAsync(); //中斷背景程式
}

private void todo(BackgroundWorker worker, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++ )
    {
        if (worker.CancellationPending) //如果被中斷...
        {
            e.Cancel = true;
            break;
        }
        System.Threading.Thread.Sleep(300); //延遲300毫秒
        this.msg = "第 " + i + " 圈 ... \r\n"; //設定訊息
        worker.ReportProgress(i); //回報進度
    }
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    if (backgroundWorker1.CancellationPending) //如果被中斷...
        e.Cancel = true;

    BackgroundWorker worker = (BackgroundWorker)sender;
    this.todo(worker, e); //欲背景執行的function
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    this.textBox1.Text += msg;
    this.textBox1.SelectionStart = this.textBox1.Text.Length;
    this.textBox1.ScrollToCaret();
    this.textBox1.Refresh();
    this.progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if ((e.Error != null))
        MessageBox.Show(e.Error.Message);
    else if (e.Cancelled)
        MessageBox.Show("使用者中斷程式");
    else
        MessageBox.Show("完成");

    this.progressBar1.Visible = false; //隱藏進度條
    this.timer1.Stop(); //停止計時器
}

private void timer1_Tick(object sender, EventArgs e)
{
    this.TimerTick = this.TimerTick.AddSeconds(1); //計時器 每秒+1
    this.label1.Text = this.TimerTick.ToString("HH:mm:ss"); //設定顯示格式
}
'VB

'---------設計畫面時的設定---------
Me.button1.Text = "開始"
Me.button2.Text = "停止"
Me.textBox1.Multiline = True '多行
Me.textBox1.ScrollBars = ScrollBars.Vertical '顯示垂直捲軸
Me.backgroundWorker1.WorkerReportsProgress = True '回報進度
Me.backgroundWorker1.WorkerSupportsCancellation = True '允許中斷
Me.timer1.Interval = 1000
'--------------------------------

Private msg As String '存放回報訊息
Private TimerTick As DateTime '計時器時間

Private Sub button1_Click(sender As Object, e As EventArgs)
    Me.TimerTick = DateTime.Parse("2000/1/1 00:00:00") '初始時間點
    Me.timer1.Start() '啟動計時器
    Me.progressBar1.Visible = True '顯示進度條
    Me.backgroundWorker1.RunWorkerAsync() '呼叫背景程式
End Sub

Private Sub button2_Click(sender As Object, e As EventArgs)
    Me.backgroundWorker1.CancelAsync() '中斷背景程式
End Sub

Private Sub todo(worker As BackgroundWorker, e As DoWorkEventArgs)
    For i As Integer = 1 To 100
        If worker.CancellationPending Then '如果被中斷...
            e.Cancel = True
            Exit For
        End If
        System.Threading.Thread.Sleep(300) '延遲300毫秒
        Me.msg = "第 " & i & " 圈 ... " & vbCr & vbLf '設定訊息
        worker.ReportProgress(i) '回報進度
    Next
End Sub

Private Sub backgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs)
    If backgroundWorker1.CancellationPending Then '如果被中斷...
        e.Cancel = True
    End If

    Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    Me.todo(worker, e) '欲背景執行的function
End Sub

Private Sub backgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
    Me.textBox1.Text += msg
    Me.textBox1.SelectionStart = Me.textBox1.Text.Length
    Me.textBox1.ScrollToCaret()
    Me.textBox1.Refresh()
    Me.progressBar1.Value = e.ProgressPercentage
End Sub

Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
    If (e.Error IsNot Nothing) Then
        MessageBox.Show(e.Error.Message)
    ElseIf e.Cancelled Then
        MessageBox.Show("使用者中斷程式")
    Else
        MessageBox.Show("完成")
    End If

    Me.progressBar1.Visible = False '隱藏進度條
    Me.timer1.Stop() '停止計時器
End Sub

Private Sub timer1_Tick(sender As Object, e As EventArgs)
    Me.TimerTick = Me.TimerTick.AddSeconds(1) '計時器 每秒+1
    Me.label1.Text = Me.TimerTick.ToString("HH:mm:ss") '設定顯示格式
End Sub

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

//C#

//開啟檔案
OpenFileDialog OpenFileDialog1 = new OpenFileDialog();
OpenFileDialog1.CheckFileExists = true;
OpenFileDialog1.Filter = "txt files (*.txt)|*.txt";
OpenFileDialog1.Multiselect = false;
OpenFileDialog1.ShowDialog();
TextBox.Text = OpenFileDialog1.FileName;

//開啟資料夾
FolderBrowserDialog FolderBrowserDialog1= new FolderBrowserDialog();
FolderBrowserDialog1.ShowDialog();
TextBox.Text = FolderBrowserDialog1.SelectedPath;
'VB

'開啟檔案
Dim OpenFileDialog1 As OpenFileDialog = New OpenFileDialog
OpenFileDialog1.CheckFileExists = True
OpenFileDialog1.Filter = "txt files (*.txt)|*.txt"
OpenFileDialog1.Multiselect = False
OpenFileDialog1.ShowDialog()
TextBox.Text = OpenFileDialog1.FileName

'開啟資料夾
Dim FolderBrowserDialog1 As FolderBrowserDialog = New FolderBrowserDialog
FolderBrowserDialog1.ShowDialog()
TextBox.Text = FolderBrowserDialog1.SelectedPath

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

C#
//檢查檔案是否存在
if (!File.Exists(FilePath))
{
    MessageBox.Show("找不到檔案");
    return;
}

StreamReader objReader = new StreamReader(FilePath);
string sLine = "";
ArrayList arrText = new ArrayList();

do
{
    sLine = objReader.ReadLine();
    if (sLine != null)
    {
        arrText.Add(sLine);
    }
} while (sLine != null);
objReader.Close();

//把讀取檔案的結果放到ListBox,您也可以另做運用。
ListBox.Items.AddRange(arrText);
VB
'檢查檔案是否存在
If Not FileIO.FileSystem.FileExists(FilePath) Then
    MsgBox("找不到檔案")
    Return
End If

Dim objReader As New StreamReader(FilePath)
Dim sLine As String = ""
Dim arrText As New ArrayList()

Do
    sLine = objReader.ReadLine()
    If Not sLine Is Nothing Then
        arrText.Add(sLine)
    End If
Loop Until sLine Is Nothing
objReader.Close()

'把讀取檔案的結果放到ListBox,您也可以另做運用。
ListBox.Items.AddRange(arrText)

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

1 2345