2013年12月24日 星期二

[除錯] 無法繫結至 DataSource 上的屬性或欄位 或 無法清除這個清單

原因:
Error:無法繫結至 DataSource 上的屬性或欄位
            bs_tblT內外銷統計附檔.DataMember = null;
            bs_tblT內外銷統計附檔.DataSource = null;

Error:無法清除這個清單
            bs_tblT內外銷統計附檔.Clear();

解決:
用bindingsource isbindingsuspended


            foreach (Control item in this.tableLayoutPanel1.Controls)
            {
                item.DataBindings.Clear();
            }
            lbl_檔案名稱.DataBindings.Clear();  
            //忘記把這個ctl給DataBindings.Clear()...
            //因為此ctl是屬於flowLayoutPanel2
            //而flowLayoutPanel2是屬於tableLayoutPanel1
            //所以此ctl我需要另外將其DataBindings.Clear()
            //而不是寫在foreach裡面...那邊只會找到flowLayoutPanel2

參考:
我的表單本來可以開啟的,因為我把access資料庫裡的欄位user改成user_1
[除錯] System.InvalidCastException: System.Data.DataViewManagerListItemTypeDescriptor
如何在dataTable更新完成後,才讓綁定的dataGridView 做更新?

2013年12月13日 星期五

[除錯] entilb DAAB [The type Database cannot be constructed. You must configure the container to supply this value]

 問題:
The type Database cannot be constructed. You must configure the container to supply this value.

Activation error occured while trying to get instance of type Database, key "ExpSys.Properties.Settings.ConnSqlStr"

解決:
組件[YC_ExpSys.exe]
設定檔[YC_ExpSys.exe.config]

當組件在組件[DayCensorWinApp.exe]上運行時
設定檔[DayCensorWinApp.exe.config]需新增設定檔[YC_ExpSys.exe.config]的設定資料
因為是由[DayCensorWinApp.exe]開啟[YC_ExpSys.exe]
而其設定檔是讀[DayCensorWinApp.exe.config]

環境:
entlib 5.0
vs2010
.net 3.5 sp1

參考:
The type Database cannot be constructed. You must configure the container to supply this value.
The type Database cannot be constructed. You must configure the container to supply this value (EntLib 5 + ODP.NET)
Activation error occured while trying to get instance of type Database, key "cnx"
Activation error occured while trying to get instance of type Database, key “” <— blank
Enterprise Library 5 with ODP.NET

2013年12月12日 星期四

[SQL] 去除欄位中(或左右兩邊)的空白

Q:
在SELECT COUNT(*)時都無法正確取得數量...
故猜測是多了空白...

A:
某A在插入CustomerOrderNo時, 右邊多了N個空白...

Solution Code:
SELECT a.CustomerOrderNo,a.CustomerOrderDate,a.CustomerID,a.CompanyName,(SELECT count(*) FROM [tblT出貨統計資料表] WHERE CustomerOrderNo = replace(a.CustomerOrderNo,' ','')) as Qty
FROM [tblT訂單統計資料表] as a LEFT JOIN [tblODeliveryOrder] as b on a.CustomerOrderNo = b.CustomerOrderNo WHERE b.DeliveryOrderNo = 'PO201210030';

參考:
去除MS SQL欄位中空白
sql字串去除左右空白字元
SQL Trim 函數

2013年11月14日 星期四

[除錯] 因為程式無法認可或結束儲存格值的變更

情況:
承自 DataGridView 的擴展控項 myDataGridView
當CellValidating...沒過...Coding為e.cancel=true;
則程式最先進入控項的ProcessDialogKey...
當Cdoing為base.CurrentCell = base.Rows[base.CurrentCell.RowIndex].Cells[nextColumn.Index];
便會出現錯誤訊息「因為程式無法認可或結束儲存格值的變更」
所以要改寫以下...(紅色+判斷)
        protected override bool ProcessDialogKey(System.Windows.Forms.Keys keyData)
        {
            //MessageBox.Show(this.CurrentCell.RowIndex.ToString());
            if (keyData == Keys.Tab || keyData == Keys.Enter)
            {
                if ((base.CurrentCell == null))
                {
                    return true;
                }
                DataGridViewColumn nextColumn = null;
                nextColumn = base.Columns.GetNextColumn(base.Columns[base.CurrentCell.ColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                if ((nextColumn != null))
                {
                    if(this.CurrentCell.IsInEditMode)
                        //當驗證沒過時, Coding部份為e.cancel=true, 使用這個方式就不會出錯了!
                        return base.ProcessDialogKey(Keys.Tab); 
                    else
                        base.CurrentCell = base.Rows[base.CurrentCell.RowIndex].Cells[nextColumn.Index];

                }
                else
                {
                    nextColumn = base.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                    if ((base.CurrentCell.RowIndex + 1) == base.Rows.Count)
                    {
                        base.CurrentCell = base.Rows[0].Cells[nextColumn.Index];
                    }
                    else
                    {
                        if (this.CurrentCell.IsInEditMode)
                            //當驗證沒過時, Coding部份為e.cancel=true, 使用這個方式就不會出錯了!
                            return base.ProcessDialogKey(Keys.Tab); 
                        else
                            base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[nextColumn.Index];
                    }
                }
                //MessageBox.Show(this.CurrentCell.RowIndex.ToString());
                return true;
            }
            return base.ProcessDialogKey(keyData);
        }

參考:
[C#]DataGridView欄位驗證只能是數字且不能為空白
DataGridView.Rows.Clear() raise exception 
You received exception message Exception.InvalidOperation "Operation did not succeed because the program cannot commit or quit a cell value change." . If this DataGridView cell is in edit mode, you have to end/submit edit and then continue.

DataGridView 控制項 (Windows Form)

2013年10月7日 星期一

[SQL] SQL SERVER 如何區分大小寫?

String[] SqlQry = new String[1];
SqlQry[0] = "SELECT * FROM [A000幣別] WHERE 幣別編號 like @幣別編號 Collate Chinese_Taiwan_Stroke_CS_AS;";

DictionaryEntry[] SqlParas = new DictionaryEntry[1];
SqlParas[0].Key = "幣別編號";
SqlParas[0].Value = "%E%";

參考:
SQL SERVER 如何區分大小寫?
[SQL SERVER][Memo]如何設定Column區分大小寫

2013年9月28日 星期六

[學習] 在HashTable容器上做Object的存取...

說明:
當cmb事件觸發時, 根據cmb.SelectedValue做為HashTable的Key
並取出對應Key的Value值...
而Value為一個類別(cls_marking)...

C#:
[cls_marking.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExportSys
{
    class cls_marking
    {
        private bool _disposed = false;

        private String _mk1;
        private String _mk2;
        private String _mk3;
        private String _mk4;
        private String _mk5;
        private String _mk6;
        private String _mk7;
        private String _mk8;
        private String _mk9;

        //建構子
        //public cls_marking(String g,String b);

        public cls_marking(String mk1, String mk2,
            String mk3, String mk4,
            String mk5, String mk6,
            String mk7, String mk8, String mk9)
        {
            this._mk1 = mk1;
            this._mk2 = mk2;
            this._mk3 = mk3;
            this._mk4 = mk4;
            this._mk5 = mk5;
            this._mk6 = mk6;
            this._mk7 = mk7;
            this._mk8 = mk8;
            this._mk9 = mk9;
            this._disposed = false;
        }

        public override string ToString()
        {
            return _mk1 + " " + _mk2 + " " + _mk3 + " " + _mk4 + " " + _mk5 + " " + _mk6 + " " + _mk7 + " " + _mk8 + " " + _mk9;
        }

        public string mk1
        {
            get { return _mk1; }
            set { _mk1 = value; }
        }

        public string mk2
        {
            get { return _mk2; }
            set { _mk2 = value; }
        }

        public string mk3
        {
            get { return _mk3; }
            set { _mk3 = value; }
        }

        public string mk4
        {
            get { return _mk4; }
            set { _mk4 = value; }
        }

        public string mk5
        {
            get { return _mk5; }
            set { _mk5 = value; }
        }

        public string mk6
        {
            get { return _mk6; }
            set { _mk6 = value; }
        }

        public string mk7
        {
            get { return _mk7; }
            set { _mk7 = value; }
        }

        public string mk8
        {
            get { return _mk8; }
            set { _mk8 = value; }
        }

        public string mk9
        {
            get { return _mk9; }
            set { _mk9 = value; }
        }

        public void Dispose()
        {
            Dispose(true);

            // Use SupressFinalize in case a subclass
            // of this type implements a finalizer.
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            // If you need thread safety, use a lock around these
            // operations, as well as in your methods that use the resource.
            if (!_disposed)
            {
                if (disposing)
                {
                    if (_mk1 != null)
                    {
                        _mk1 = null;
                        _mk2 = null;
                        _mk3 = null;
                        _mk4 = null;
                        _mk5 = null;
                        _mk6 = null;
                        _mk7 = null;
                        _mk8 = null;
                        _mk9 = null;
                    }
                    Console.WriteLine("Object disposed.");
                }

                // Indicate that the instance has been disposed.
                _mk1 = null;
                _mk2 = null;
                _mk3 = null;
                _mk4 = null;
                _mk5 = null;
                _mk6 = null;
                _mk7 = null;
                _mk8 = null;
                _mk9 = null;
                _disposed = true;
            }
        }
    }
}

[ExpOrder.cs]
private Hashtable htb_mark = new Hashtable();

private void cmdBing()
{
       cmb_印字編號.DisplayMember = "Value";
       cmb_印字編號.ValueMember = "Key";
       ArrayList al = new ArrayList();
       using (IDataReader reader = db.ExecuteReader(db.GetSqlStringCommand("SELECT MARK代碼 + '(' + 中文名稱 + ')' as 中文名稱,MARK代碼,MARK1,MARK2,MARK3,MARK4,MARK5,MARK6,MARK7,MARK8,MARK9 FROM [tbl資料表];")))
       {
              if (htb_mark.Count > 0) htb_mark.Clear();
              while (reader.Read())
              {
                        al.Add(new DictionaryEntry(reader.GetValue(1), reader.GetValue(0)));

                        cls_marking mark = new cls_marking(reader["MARK1"].ToString(), reader["MARK2"].ToString(),
                            reader["MARK3"].ToString(), reader["MARK4"].ToString(), reader["MARK5"].ToString(), 
                            reader["MARK6"].ToString(), reader["MARK7"].ToString(), reader["MARK8"].ToString(), 
                            reader["MARK9"].ToString());
                        
                        htb_mark.Add(reader["MARK代碼"].ToString(), mark);
               }
                    cmb_印字編號.DataSource = al;
        }
}

private void cmb_印字編號_SelectedIndexChanged(object sender, EventArgs e)
{
     this.txt_印字1.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk1.ToString();
     this.txt_印字2.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk2.ToString();
     this.txt_印字3.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk3.ToString();
     this.txt_印字4.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk4.ToString();
     this.txt_印字5.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk5.ToString();
     this.txt_印字6.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk6.ToString();
     this.txt_印字7.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk7.ToString();
     this.txt_印字8.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk8.ToString();
     this.txt_印字9.Text = ((cls_marking)htb_mark[cmb_印字編號.SelectedValue]).mk9.ToString();
}

private void btn_Test(object sender, EventArgs e)
{
     //法一
     foreach(DictionaryEntry item in htb_mark)
     {
          MessageBox.Show(item.Key + " = " + ((cls_marking)item.Value).mk1);
     }

     //法二
     foreach(cls_marking item in htb_mark.Values)
     {
          MessageBox.Show(item.mk1.ToString());
      }

//法三
//variable to hold the list of songs
string list = string.Empty;
//create an instance of the IDictionaryEnumerator Interface
IDictionaryEnumerator enumerator;
//make sure our Hashtable holds items
if (htb_mark.Count > 0)
{
     //let the user know what we're doing
     MessageBox.Show("The following songs are in your list:");      
     //now set out IDictionaryEnumerator value
     enumerator = htb_mark.GetEnumerator();      
     //now use the MoveNext Method to iterate through our list
     while (enumerator.MoveNext())
     {
          //keep adding song names until we reach the end
          list += enumerator.Value.ToString() + "\r\n";
     }
     //now show the song names
     MessageBox.Show(list);
}

}

缺點:
C# - 替代 Hashtable 沒有泛型的方案
雖然Hashtable在某些地方很好用,但在某些情況下,反而成了礙手礙腳的。
Hashtable裡面的物件都是存成object,倘若要不斷的使用物件,就要不斷的轉型…
一來折損不少效能,二來程式碼看起來就很不舒服

其實,解決方法有很多種,只是找不到有詳盡介紹 C# 所有Collections的好文章。
最根本的做法就是直接去實作Collections使用的介面,但是又整個很麻煩的感覺。
一直在想,都有List<>的泛型了,為啥沒有對應
Hashtable的泛型咧~
今天終於給我咕到一個好用的Collections可以取代之!

參考:
DictionaryEntry 結構
C#集合--Dictionary

Hashtable 類別
C#中HashTable的用法
C#中如何操作HashTable类呢?
Hashtablekey, value键值对均为object类型,所以Hashtable以支持任何类型的keyvalue键值对.

C#集合之Hashtable
C# 應用雜湊表(Hashtable)
什麼是 Dictionaries
Using The C# Hashtable Collection
C# Hashtable
C#: Storing Instance of Objects in (Hashtable)

How to Serialize a Dictionary or Hashtable in C#

使用泛型類別解決 ComboBox 的自訂資料繫結問題

集合與泛型對應
c#中Dictionary、ArrayList、Hashtable和数组 Array 的区别
Array和ArrayList的异同点