2013年1月28日 星期一

[SQL] UPDATE + SELECT 避免 Race Condition & 兩table多筆更新

即然有 insert 與 select 的結合
當然也有 update 與 select 的結合


UPDATE
    tblA
SET
    上年同期內銷 = B.內銷合計,
上年同期外銷 = B.外銷台幣,
外銷上年同期美國 = B.外銷美國,
外銷上年同期日本 = B.外銷日本,
外銷上年同期其他 = B.外銷其他,
外銷上年同期重量 = B.外銷重量
FROM   tblA AS A
    INNER JOIN
(SELECT '2019' 年度,月份,ISNULL(內銷合計,0) 內銷合計,ISNULL(外銷台幣,0) 外銷台幣,ISNULL(外銷美國,0) 外銷美國,ISNULL(外銷日本,0) 外銷日本,ISNULL(外銷其他,0) 外銷其他,ISNULL(外銷重量,0) 外銷重量 FROM tblB where 年度='2018') AS B
ON A.年度 = B.年度 and A.月份=B.月份
WHERE
    A.年度 = '2019'


另一篇:
INSERT & SELECT

用 SELECT ... FOR UPDATE 避免 Race condition

2013年1月23日 星期三

[SQL] 流水號(自動編號), 補上缺號...

問題:
ex: 流水序號(限integer編碼)
0 1 2 5 6 8 12 下一次 補上 3(最小號缺號) or 補上 11(最大號缺號)
0 1 2 3 4 5 最大(或最小) 都會補6

解決:
找出缺號中的最大值
select max(staff_sn-1) as lostnum from employee where (not ((staff_sn-1) in (select staff_sn from employee)))

select max(序號)-1 from [A010詢價單資料表-備註] a
where not exists(select 1 from [A010詢價單資料表-備註] where 序號=a.序號-1 and 詢價單號 = 'AA01') and 詢價單號 = 'AA01';

select   top   1   t1.序號-1   from    [A010詢價單資料表-備註]   t1
where   not   exists   (   select   1   from    [A010詢價單資料表-備註]   t2   where   t2.序號   =   t1.序號   -1  and t2.詢價單號 = 'AA01' )  and t1. 詢價單號 = 'AA01'
order   by   t1.序號 DESC

注意:(有待改進)
若是 5 6 7 則補號為 4 而不是 8 -- 序號間無缺號
若是 1 2 3 則補號為 0
若是 0 1 2  則補號為 -1

-------------------------------

找出缺號中的最小值
select min(staff_sn+1) as lostnum from employee where (not ((staff_sn+1) in (select staff_sn from employee)))

select max(序號)+1 from [A010詢價單資料表-備註] a
where not exists(select 1 from [A010詢價單資料表-備註] where 序號=a.序號+1 and 詢價單號 = 'AA01') and 詢價單號 = 'AA01';

select   top   1   t1.序號+1   from    [A010詢價單資料表-備註]   t1
where   not   exists   (   select   1   from    [A010詢價單資料表-備註]   t2   where   t2.序號   =   t1.序號   +1  and t2.詢價單號 = 'AA01' )  and t1. 詢價單號 = 'AA01'
order   by   t1.序號

注意:(有待改進)
若是 3 6 7 則補號為 4 而不是 1
若是 5 6 7 則補號為 8 而不是 1 -- 序號間無缺號

-------------------------------

正式應用:
insert into [Usys使用者資料表] (使用者ID)  select min(使用者ID+1)  from [Usys使用者資料表] where (not ((使用者ID+1) in (select 使用者ID from [Usys使用者資料表])))


sqlQuery = "insert into [Usys使用者資料表] (使用者ID,帳號,密碼,使用者名稱,Email,CreateDate,CreateUserID,CreateUserName," & _
            "ModifyDate,ModifyUserID,ModifyUserName,SystemModifyDate)" & _
            " select min(使用者ID+1),@帳號,@密碼,@使用者名稱,@Email,@建檔日,@建檔人ID,@建檔人," & _
            "@修檔日,@修檔人ID,@修檔人,@系統修檔日  from [Usys使用者資料表]" & _
            " where (not ((使用者ID+1) in (select 使用者ID from [Usys使用者資料表])));"

另一種insert的正式應用:
                '找出 使用者 在此系統別下 所缺的程式...
                'select 程式ID from Usys系統別程式資料表 where 系統ID = 1 and 程式ID not in (select 程式ID from Usys使用者程式資料表 where 使用者ID = 5);

                '找將找出的程式record (多筆) 一筆一筆新增到Usys使用者程式資料表
                Dim sqlQuery_Progs As String = "insert into [Usys使用者程式資料表] (使用者ID,程式ID) select " & DataGridView1.CurrentRow.Cells(0).Value & ",  程式ID from Usys系統別程式資料表 where 系統ID = " & Microsoft.VisualBasic.Left(frmEdit.ComboBox1.Text, InStr(frmEdit.ComboBox1.Text, "(") - 1) & " and 程式ID not in (select 程式ID from Usys使用者程式資料表 where 使用者ID = " & DataGridView1.CurrentRow.Cells(0).Value & ")"
                ',權限,執行權限,新增權限,修改權限,刪除權限,管理權限 DB已經有設置預設值都是 0

(承上)用另種方式來新增insert:
找出系統ID下的所有程式ID(Usys系統別程式資料表) 之後新增給 Usys使用者程式資料表 如果要新增的這個程式ID 並不存在於 Usys使用者程式資料表(即原本就存在就 不需再新增)
insert into Usys使用者程式資料表 (使用者ID,程式ID) select 5,程式ID from Usys系統別程式資料表 Where 系統ID = 1 and not exists (select * from Usys使用者程式資料表 where Usys系統別程式資料表.程式ID = Usys使用者程式資料表.程式ID)


缺點:
若無序號列存在,即無缺號被找到...
固也無法新增... (因為是null) insert 失敗!!
所以在新增前必須判斷缺號 count(id) 是否>0
若count(id) = 0 則 insert 時的序號 直接給定 1(sql字串 要換掉)

解決:沒有資料列時 則補1

select case when min(序號+1) is NULL then 1 else min(序號+1) end as lostnum from  [A010詢價單資料表-備註] where (not ((序號+1) in (select 序號 from  [A010詢價單資料表-備註] where 詢價單號 = 'AA01'))) and 詢價單號 = 'AA01';


最理想的解決--找出最小值:(等待神的出現....)
沒有資料列時 則補1
有資料列時 5 7 8 9 則補1 而不是 補6
有資料列時 6 7 8 9 則補1 而不是 補10(或4)


select & insert
insert into [tableDetail] (報表編號, 內容, 建檔日, 建檔人, 建檔人ID, 修檔日, 修檔人, 修檔人ID,系統修檔日)
 select 報表編號, 瑕疵原因, 建檔日, 建檔人, 建檔人ID, 修改日, 修改人, 修改人ID,系統修改日 from [tableMain];

另一篇:
UPDATE & SELECT

參考:
藍色小惡魔討論區: SQL
SQL 自製流水號做法(有規律的序號)
SQL-自動補流水號
新增資料時自動產生識別代號的一些方法

获取自动编号的问题(经典实用)
返回已用编号、缺号分布字符串的处理示例
融合了补号处理的编号生成处理示例
SQL语句处理流水号编号补号
流水號自動補號和計算所缺最小號和最大號
自动生成序号的存储过程
编号连续不能断号,断号后补号
[SQL] 流水號跳號
DB建置流水號問題
如何找出缺少的單據編號?能否用一個Select語句實現?
請問如何設計查詢找出缺的單號

数据库 查询缺号列出缺号的所有号码
UPDATE OR INSERT in one statement
SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
第二種 INSERT INTO 能夠讓我們一次輸入多筆的資料。
使用 INSERT 與 SELECT 加入資料列
一次新增多筆資料 - INSERT ... SELECT
如何找到資料表某欄位第一個缺號的數值
SELECT INTO 和 INSERT INTO SELECT 區別
使用 INSERT 與 SELECT 加入資料列

避免自動增量 衝突pt1
避免自動增量 衝突pt2

一列数据存了一组不连续的正整数,求一SQL查询空缺的最小的值
Oracle层次查询和分析函数在号段选取中的应用

用VBA解決 自動編號的主KEY insert缺號

SQL::CASE, NULLIF() and ISNULL()
ISNULL (Transact-SQL)
NULLIF (Transact-SQL)
SQL - 使用 NULLIF
SQLServer 中的 ISNULL 和 NULLIF
SQL SERVER – Explanation and Comparison of NULLIF and ISNULL

[技巧] ReportViewer 動態改變字型大小 change/modify dyanamically/programmatically rdlc font/size

原因:
當某些欄位的文字長度超過rdlc設計時的文字方塊大小
列印時欄位便會自動擴大,因而造成報表跑位(拉長或拉寬) or 多出一頁的錯誤

解決:
透過動態改變字型大小即可解決
在文字方塊 - 屬性 - Font - FontSize 運算式
=iif(Len(Parameters!Report_Parameter_0.Value)>= 200,10,12) & "pt"

當參數值Report_Parameter_0 經過 Len()函式 運算出來的 字串長度 > 200 時
設定字型為 10pt Else 設定字型為 12pt


它解:
一、載入rdlc前,改修rdlc(xml)

二、寫在 rdlc code

2013年1月10日 星期四

[技巧] String Format 格式化, 自動補零, 不足位元補零...

Dim s As String = "1512"
s = String.Format("{0:0000}", (Microsoft.VisualBasic.Right(s, 3) + 1))

Result:
s = "0513"

s = "12"
s=s.PadLeft(3, Convert.ToChar("0")

Result:
s = "012"

參考:
[SQL] 不足位數補上零 "0"
请教字符串前面自动补零
用String.Format將輸出給格式化
標準數值格式字串
C# tostring 格式化输出
C# .ToString() 格式化
.net 中通用的formatstring格式符整理
SQL 流水號字串補零
ToString() 格式化文字
Tostring 格式化输出字符串全解
自訂數值格式字串
[.NET] 不足位元補 0
String.PadLeft 方法 (Int32, Char)
TIPS-.NET DateTime Formating
[C#]簡單快速將各種數值字數轉成數字(string to int)

其它(日期)參考:
時間格式及方法運用
標準日期和時間格式字串
DateTime.GetDateTimeFormats 方法
DateTimeFormatInfo 類別
用DateTimeFormatInfo格式化日期时间(C#)
AM and PM with "Convert.ToDateTime(string)"
how get a.m. p.m. from DateTime?
自訂日期和時間格式字串
datetime.now first and last minutes of the day
SQL时间类型(DateTime)模糊查询及Between
善用 SQL Server 中的 CONVERT 函數處理日期字串
[SQL]使用BETWEEN要注意的地方
[筆記] SQL - between

[學習] DataGridView 資料繫結 與 資料清除

資料顯示方式:
DataGridView1.DataSource = ds.Tables(0)

資料清除方式:
DataGridView1.DataSource = Nothing
DataGridView1.Refresh()

========================================
資料顯示方式:
For i As Integer = 0 To ds.Tables("family").Rows.Count - 1
     DataGridView2.Rows.Add(
          ds.Tables("family").Rows(i)(0),
          ds.Tables("family").Rows(i)(1),
          ds.Tables("family").Rows(i)(2),
          ds.Tables("family").Rows(i)(3),
          ds.Tables("family").Rows(i)(4))
Next

資料清除方式:
DataGridView2.Rows.Clear()

Error Msg:
無法清除這個清單

參考:
DataGridView全部删除不成功

2013年1月6日 星期日

[技巧] N個控制項驗證寫在同一個事件處理時, 判斷是由哪個控制項觸發事件

[VB.NET]
Private Sub ComboBox_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ComboBox2.Validating, ComboBox1.Validating, ComboBox3.Validating, ComboBox4.Validating
        'MsgBox(e.ToString)
        'MsgBox(sender.ToString)
        'Exit Sub

        '避免視窗關閉時(引發驗證事件)
        If frmClose = True Then
            Exit Sub
        End If

        '表示都沒有更動, 所以也就不需要再做下面的判斷 -> 新值 = 舊值
        If Me._btnOperation = "update" AndAlso ComboBox1.Text.Trim = Trim(ComboBox1.Tag) AndAlso _
            ComboBox2.Text.Trim = Trim(ComboBox2.Tag) AndAlso _
            ComboBox3.Text.Trim = Trim(ComboBox3.Tag) AndAlso _
            ComboBox4.Text.Trim = Trim(ComboBox4.Tag) Then
            Exit Sub
        End If
        'MsgBox(e.ToString)

        '取得目前焦點位置....
        'MsgBox(CType(sender, Control).Name)
        'Exit Sub

        If (CType(sender, Control).Name = "ComboBox2" OrElse CType(sender, Control).Name = "ComboBox3") _
        AndAlso Me._btnOperation = "update" AndAlso Me.DataGridView1.Rows.Count > 0 _
        AndAlso (ComboBox2.Text.Trim <> Trim(ComboBox2.Tag) OrElse _
                         ComboBox3.Text.Trim <> Trim(ComboBox3.Tag)) Then

            MsgBox("有單據明細資料不能修改此欄位, 請重新輸入!")
            ComboBox2.Text = ComboBox2.Tag
            ComboBox3.Text = ComboBox3.Tag
            Exit Sub
        End If


        If _Editing = True Then

            If String.IsNullOrEmpty(Me.ComboBox2.Text) Then
                MsgBox("材質編號空白, 請重新輸入!")
                ErrorProvider1.SetError(Me.ComboBox2, "材質編號空白, 請重新輸入!")
                Me.ComboBox2.Focus()
                Exit Sub
            ElseIf Me.ComboBox2.SelectedIndex = -1 Then
                MsgBox("材質編號不允許自行輸入, 請重新選擇!")
                ErrorProvider1.SetError(Me.ComboBox2, "材質編號不允許自行輸入, 請重新選擇!")
                Me.ComboBox2.Focus()
                Exit Sub
            End If

            If String.IsNullOrEmpty(Me.ComboBox3.Text) Then
                MsgBox("牌價編號空白, 請重新輸入!")
                ErrorProvider1.SetError(Me.ComboBox3, "牌價編號空白, 請重新輸入!")
                Me.ComboBox3.Focus()
                Exit Sub
            ElseIf Me.ComboBox3.SelectedIndex = -1 Then
                MsgBox("牌價編號不允許自行輸入, 請重新選擇!")
                ErrorProvider1.SetError(Me.ComboBox3, "牌價編號不允許自行輸入, 請重新選擇!")
                Me.ComboBox3.Focus()
                Exit Sub
            End If

            If String.IsNullOrEmpty(Me.ComboBox1.Text) Then
                MsgBox("業務員編號空白, 請重新輸入!")
                ErrorProvider1.SetError(Me.ComboBox1, "業務員編號空白, 請重新輸入!")
                Me.ComboBox1.Focus()
                Exit Sub
            ElseIf Me.ComboBox1.SelectedIndex = -1 Then
                MsgBox("業務員編號不允許自行輸入, 請重新選擇!")
                ErrorProvider1.SetError(Me.ComboBox1, "業務員編號不允許自行輸入, 請重新選擇!")
                Me.ComboBox1.Focus()
                Exit Sub
            End If

            If String.IsNullOrEmpty(Me.ComboBox4.Text) Then
                MsgBox("幣別欄位空白, 請重新輸入!")
                ErrorProvider1.SetError(Me.ComboBox4, "幣別欄位空白, 請重新輸入!")
                Me.ComboBox4.Focus()
                Exit Sub
            ElseIf Me.ComboBox4.SelectedIndex = -1 Then
                MsgBox("幣別欄位不允許自行輸入, 請重新選擇!")
                ErrorProvider1.SetError(Me.ComboBox4, "幣別欄位不允許自行輸入, 請重新選擇!")
                Me.ComboBox4.Focus()
                Exit Sub
            End If

            '取消事件
            'e.Cancel = True
        End If

        ErrorProvider1.SetError(Me.ComboBox1, "")
        ErrorProvider1.SetError(Me.ComboBox2, "")
        ErrorProvider1.SetError(Me.ComboBox3, "")
        ErrorProvider1.SetError(Me.ComboBox4, "")
    End Sub


[C#.NET]
        private void txt_訂購單號_Validating(object sender, CancelEventArgs e)
        {
            if (this._Editing==false)
                return;

            //MessageBox.Show(typeof((Control)sender));
            //MessageBox.Show((sender).GetType().ToString());
            //MessageBox.Show(((Control)sender).GetType().ToString());
            //MessageBox.Show(this.ActiveControl.Name);

            //switch (sender.GetType().ToString())
            //{
            //    case "TextBox":
            //        MessageBox.Show("AA");
            //        break;
            //}

            Regex rx;
            if (sender is TextBox)
            {
                //if (((TextBox)sender).Name == "")
                //{

                //}

                switch (((TextBox)sender).Name)
                {
                    case "txt_訂購單號":
                        rx = new Regex(@"^[\S]{1,15}$");
                        if (!rx.IsMatch(txt_訂購單號.Text.Trim()))
                        {
                            MessageBox.Show(
                                this,
                                "訂購單號:不可空白, 長度不可超過15!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_訂購單號, "不可空白, 長度不可超過15!!");
                            //txt_訂購單號.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_AD":
                        rx = new Regex(@"^(25[0-5]|2[0-4]\d|[1]\d{2}|[0-9]{0,2})$");
                        if (!rx.IsMatch(txt_AD.Text.Trim()))
                        {
                            MessageBox.Show(
                                this,
                                "AD:請輸入數值0-255!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_AD, "請輸入數值0-255!!");
                            //txt_AD.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_註記":
                        rx = new Regex(@"^[\S]{0,50}$");
                        if (!rx.IsMatch(txt_註記.Text.Trim()))
                        {
                            MessageBox.Show(
                                this,
                                "註記:長度不可超過50!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_註記, "長度不可超過50!!");
                            //txt_註記.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_客戶訂號":
                        rx = new Regex(@"^[\S]{0,20}$");
                        if (!rx.IsMatch(txt_客戶訂號.Text.Trim()))
                        {
                            MessageBox.Show(
                                this,
                                "註記:長度不可超過20!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_客戶訂號, "長度不可超過20!!");
                            //txt_客戶訂號.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_詢單編號":
                        rx = new Regex(@"^[\S]{0,15}$");
                        if (!rx.IsMatch(txt_詢單編號.Text.Trim()))
                        {
                            MessageBox.Show(
                                this,
                                "詢單編號:長度不可超過15!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_詢單編號, "長度不可超過15!!");
                            //txt_客戶訂號.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_交易條件":
                    case "txt_付款方式":
                        rx = new Regex(@"^[\S]{0,50}$");
                        if (!rx.IsMatch(((TextBox)sender).Text.Trim()))
                        {
                            MessageBox.Show(
                                this,
                                ((TextBox)sender).Tag + ":長度不可超過50!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(((TextBox)sender), "長度不可超過50!!");
                            //txt_客戶訂號.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_訂單金額":
                        //rx = new Regex(@"^(25[0-5]|2[0-4]\d|[1]\d{2}|[0-9]{0,2})$");
                        //if (!rx.IsMatch(txt_訂單金額.Text.Trim()))
                        //{
                        //}
                        decimal decResult = 0;
                        bool decFalg = decimal.TryParse(txt_訂單金額.Text.Trim(), out decResult);
                        if ( !decFalg || decResult < 0)
                        {
                            MessageBox.Show(
                                this,
                                "金額:請輸入正整數!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_訂單金額, "請輸入正整數!!");
                            //txt_AD.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;
                    case "txt_數量":
                        //rx = new Regex(@"^(25[0-5]|2[0-4]\d|[1]\d{2}|[0-9]{0,2})$");
                        //if (!rx.IsMatch(txt_數量.Text.Trim()))
                        //{
                        //}    
                        int intResult = 0;
                        bool intFalg = int.TryParse(txt_數量.Text.Trim(), out intResult);
                        if ( !intFalg || intResult < 0)
                        {
                            MessageBox.Show(
                                    this,
                                    "數量:請輸入正整數!!",
                                    "✚格式化錯誤✚",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                            errorProvider1.SetError(txt_數量, "請輸入正整數!!");
                            //txt_AD.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }                      
                        break;
                    default:
                        break;
                }
            }
            else if (sender is ComboBox)
            {
                switch (((ComboBox)sender).Name)
                {
                    case "cmb_客戶編號":
                    case "cmb_業務編號":
                    case "cmb_抬頭編號":
                    case "cmb_流程編號":
                    case "cmb_幣別編號":
                    case "cmb_銀行編號":
                        //rx = new Regex(@"^[\S]{0,20}$");
                        //if (!rx.IsMatch(txt_客戶訂號.Text.Trim()))
                        //}

                        if(((ComboBox)sender).SelectedIndex == -1)
                        {
                            MessageBox.Show(
                                this,
                                ((ComboBox)sender).Tag + ":請從項目中選擇!!",
                                "✚格式化錯誤✚",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            errorProvider1.SetError((Control)sender, "請從項目中選擇!!");
                            //cmb_客戶編號.Focus();
                            e.Cancel = true; //按右上角FormClose...會被取消
                        }
                        break;

                    default:
                        break;
                }
            }
         
        }

        private void txt_訂購單號_Validated(object sender, EventArgs e)
        {
            //MessageBox.Show(sender.ToString());
            errorProvider1.SetError((Control)sender, "");
            //errorProvider1.SetError(txt_訂購單號, "");
            //errorProvider1.SetError(txt_AD, "");
            //errorProvider1.SetError(txt_註記, "");
            //errorProvider1.SetError(cmb_客戶編號, "");
            //errorProvider1.SetError(cmb_業務編號, "");
            //errorProvider1.SetError(txt_客戶訂號, "");
        }

參考:
Control.Validating 事件
Control.GotFocus 事件
判斷焦點位置
[C#.NET][VB.NET] 如何設定 控制項陣列 / 動態加入控制項
[C#] 動態 button 和事件
C#動態控制項陣列化

2013年1月4日 星期五

[技巧] BindingSource.item 透過[欄位名稱] 取代 [索引值] 來取值...

假設DB一筆Row共用100個欄位(從1開始~100)
而你想要的值在第37個位置(從0開始~99)
則bs的屬性item取值如下:

(法一) 這種方式是必須去算所要的值在第幾個索引,算到頭都昏了!!
bindingsource.item(0)(37).tostring

(法二) 這種方式方便多了,當你將DB bind到 bs時,也會有欄位名稱!!
bs.item(0)("欄位名稱").tostring

ex:欄位名稱為 "匯率"
bs.item(0)("匯率").tostring

Note:
datatable,dataset,datagridview,etc... 等同道理!

[C#]
((DataRowView)bs_印字[bs_印字.Position])["MARK1"]

參考:
BindingSource.Item 屬性
http://hi.baidu.com/1981633/item/88a5cb89c071d02b110ef30c
BindingSource使用模式 - Data Binding基礎知識 (一)

2013年1月3日 星期四

[技巧] DataTable - 查詢篇 (找出所在的索引位置) 並刪除


程式:
'Dim row() As DataRow = Me.Head_dt.Select("詢價單號 = 'AA01'")
Dim row() As DataRow = Me.Head_dt.Select("詢價單號 = '" & TextBox1.Text.Trim & "'")
MsgBox(Me.Head_dt.Rows.IndexOf(row(0)))

  Note:
Select 方法會回傳 DataRow 陣列 (多筆) 
Dim row() As DataRow = Me.Head_dt.Select("詢價單號 = 'AA01'")

其它:
'MsgBox(Me.Head_dt.Select("詢價單號 = 'AA02'").Length) <-- 總共找到幾筆資料
'Me.Head_dt.Rows.RemoveAt(Me.Head_dt.Rows.IndexOf(row(0))) <-- 刪除此索引值的Row

刪除另解:DataRow會連動底層DataTable... 應該是 call by refence
        Dim dtrow() As DataRow = dt.Select("詢價單號 = '" & DataGridView1.CurrentRow.Cells("詢價單號").Value.ToString & "' and 序號 = " & DataGridView1.CurrentRow.Cells("序號").Value.ToString & "")
        'dt.Rows(0)(0) = "AA0000"
        dt.Rows(0).Delete()
从 DataTable 对象中删除 DataRow 对象 遇到的问题

備註:
若是日期格式,則 # 欄位資料 #

for i as integer = 0 to row.GetUpperBound(0)
    msgbox(row(i)("欄位名稱").Tostring)
next

參考:
How to find index of a row based on the object value? (C#)
[ADO.NET] 如何使用 DataTable / 搜尋 過濾 資料
檢視 DataTable 中的資料
DataTable Select的陷阱
DataTable (Select, Find, Compute and Linq)
Linq實踐系列(1):一句代碼實現DataTable全文搜索(Full Text Search)
在DataTable中查询应该注意的问题
对DataTable数据进行查询过滤
DataTable中的select()用法
DataTable.Compute 方法

參考2:
about DataTable.Select("FieldName=日期時間")
.net datatable 的 select 敘述使用 SQLSERVER datetime
Select in DataTable with condition on DateTime column
SUBSTRING LIKE
Datatable.Select 的運算式用法
Linq小技巧:日期處理
SQL函數 查詢SQL資料欄位相符的字串
MSSql 中Charindex ,Substring的使用
CHARINDEX (Transact-SQL)