none
表格(Table)輸出功能 RRS feed

  • 問題

  • 各位先進好!小弟目前想要完成一個功能,需求如下:

    Q1.將每一筆項目量測計算的結果輸出,大致上像這樣:

       ===========================

      項目     量測值  標準值  最大值  最小值 

      1.外俓  1        0.1      0.01    -0.01

      2.長     2        0.1      0.01    -0.01

      3.高     3        0.1       0.01    -0.01

      ============================

    這個二維的陣列計算,會隨每次的量測而量測值有所不同,

    所以目前的想法是以結構陣列去做這件事情,每量測一次就更新1.外徑2.長3.高的量測值,

    不知道小弟的想法有沒有錯誤?還是各位先進有更好的方式呢?

    Q2.我要如何將量測完的結構陣列輸出至表格,是使用DataGrindView嗎?

    我要如何設定我要的欄位與行位,因為我看書上寫的都是他直接載入他寫好的格式,

    然後直接使用,讓我疑惑!

    以上問題再請各位先進解答,感謝了

    2018年3月23日 上午 06:24

解答

  • 先在 Form 上拉一個 DataGridView 之後,再新增四個 column,以下的程式碼給你參考

    看看哪邊比較不清楚可以再提出來

    namespace Table
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                var valueSets = new List<ValueSet>();
                valueSets.Add(new ValueSet {MeasureValue = 1, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 2, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 3, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
    
                foreach( var valueSet in valueSets)
                {
                    int rowIndex = dataGridView1.Rows.Add();
                    dataGridView1[Column1.Index, rowIndex].Value = valueSet.MeasureValue.ToString();
                    dataGridView1[Column2.Index, rowIndex].Value = valueSet.StandardValue.ToString();
                    dataGridView1[Column3.Index, rowIndex].Value = valueSet.MaxValue.ToString();
                    dataGridView1[Column4.Index, rowIndex].Value = valueSet.MinValue.ToString();
                }
            }
        }
    
        internal class ValueSet
        {
            public int MeasureValue;//量測值
            public double StandardValue;//標準值
            public double MaxValue;//最大值
            public double MinValue;//最小值
        }
    }

    希望對你有幫助~

    • 已標示為解答 seanhua 2018年3月28日 上午 10:14
    2018年3月23日 上午 10:26

所有回覆

  • 先在 Form 上拉一個 DataGridView 之後,再新增四個 column,以下的程式碼給你參考

    看看哪邊比較不清楚可以再提出來

    namespace Table
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                var valueSets = new List<ValueSet>();
                valueSets.Add(new ValueSet {MeasureValue = 1, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 2, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 3, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
    
                foreach( var valueSet in valueSets)
                {
                    int rowIndex = dataGridView1.Rows.Add();
                    dataGridView1[Column1.Index, rowIndex].Value = valueSet.MeasureValue.ToString();
                    dataGridView1[Column2.Index, rowIndex].Value = valueSet.StandardValue.ToString();
                    dataGridView1[Column3.Index, rowIndex].Value = valueSet.MaxValue.ToString();
                    dataGridView1[Column4.Index, rowIndex].Value = valueSet.MinValue.ToString();
                }
            }
        }
    
        internal class ValueSet
        {
            public int MeasureValue;//量測值
            public double StandardValue;//標準值
            public double MaxValue;//最大值
            public double MinValue;//最小值
        }
    }

    希望對你有幫助~

    • 已標示為解答 seanhua 2018年3月28日 上午 10:14
    2018年3月23日 上午 10:26
  • Mystic Lin先進  您好!

    不好意思,這麼久才回覆您,因為小弟前陣子出差,

    小弟有照您的方式測試了,結果是我想要的,但是在程式碼的設計上我有些疑問,

     var valueSets = new List<ValueSet>();
                valueSets.Add(new ValueSet {MeasureValue = 1, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 2, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 3, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});

    這一段程式我的認知是利用List將要列出的資料作結合,不知有沒有錯誤?

      foreach( var valueSet in valueSets)
                {
                    int rowIndex = dataGridView1.Rows.Add();
                    dataGridView1[Column1.Index, rowIndex].Value = valueSet.MeasureValue.ToString();
                    dataGridView1[Column2.Index, rowIndex].Value = valueSet.StandardValue.ToString();
                    dataGridView1[Column3.Index, rowIndex].Value = valueSet.MaxValue.ToString();
                    dataGridView1[Column4.Index, rowIndex].Value = valueSet.MinValue.ToString();
                }

    這一段程式我有一個疑問 int rowIndex = dataGridView.Rows.Add();

    這行指令是將dataGridView.Rows累加1嗎?

    internal class ValueSet
        {
            public int MeasureValue;//量測值
            public double StandardValue;//標準值
            public double MaxValue;//最大值
            public double MinValue;//最小值

    這段程式是不是將量測值.標準值.最大值與最小值作公用變數宣告並且指定給 new List<ValueSet>使用呢?

    再請先進您指導一下,感謝萬分!

    2018年3月28日 上午 06:55
  • Mystic Lin先進  您好!

    不好意思,這麼久才回覆您,因為小弟前陣子出差,

    小弟有照您的方式測試了,結果是我想要的,但是在程式碼的設計上我有些疑問,

     var valueSets = new List<ValueSet>();
                valueSets.Add(new ValueSet {MeasureValue = 1, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 2, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
                valueSets.Add(new ValueSet {MeasureValue = 3, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});

    這一段程式我的認知是利用List將要列出的資料作結合,不知有沒有錯誤?

    沒錯,就只是用 List 把資料給蒐集起來而已。

      foreach( var valueSet in valueSets)
                {
                    int rowIndex = dataGridView1.Rows.Add();
                    dataGridView1[Column1.Index, rowIndex].Value = valueSet.MeasureValue.ToString();
                    dataGridView1[Column2.Index, rowIndex].Value = valueSet.StandardValue.ToString();
                    dataGridView1[Column3.Index, rowIndex].Value = valueSet.MaxValue.ToString();
                    dataGridView1[Column4.Index, rowIndex].Value = valueSet.MinValue.ToString();
                }

    這一段程式我有一個疑問 int rowIndex = dataGridView.Rows.Add();

    這行指令是將dataGridView.Rows累加1嗎?

    dataGridView.Rows.Add() 會真的在表格中新增一列,而回傳的 rowIndex 就是該新增列的 row index。

    internal class ValueSet
        {
            public int MeasureValue;//量測值
            public double StandardValue;//標準值
            public double MaxValue;//最大值
            public double MinValue;//最小值

    這段程式是不是將量測值.標準值.最大值與最小值作公用變數宣告並且指定給 new List<ValueSet>使用呢?

    再請先進您指導一下,感謝萬分!

    沒錯,就只是把這些幾種數值用 ValueSet 給包裝起來,而非單單用類似二維陣列的方式紀錄,這樣程式也比較好閱讀~

    以上,大概就是這樣,希望沒有誤解你的問題。


    • 已編輯 Mystic Lin 2018年3月28日 上午 08:37
    2018年3月28日 上午 08:34
  • Mystic Lin 先進,真是太感謝您詳細的指導!讓我收穫不少,感謝喔
    2018年3月28日 上午 10:13
  • Mystic Lin 先進您好!

    小弟這麼有個延伸的問題想要請問一下,

    如果我想要讓量測數值超出標準值的那一列的Table底色為紅色,

    那我該如設計程式,因為我自己測試了一下,我無法成功寫出Backgroungcolor的程式碼!

    再請先進指導一下,感謝

    2018年3月29日 上午 12:28
  • Mystic Lin 先進您好!

    小弟這麼有個延伸的問題想要請問一下,

    如果我想要讓量測數值超出標準值的那一列的Table底色為紅色,

    那我該如設計程式,因為我自己測試了一下,我無法成功寫出Backgroungcolor的程式碼!

    再請先進指導一下,感謝

    dataGridView1[0, 0].Style.BackColor = Color.Red;

    試試~~這是你要的效果嗎?

    2018年3月29日 上午 01:24
  • Mystic Lin 先進您好!

    我測試過您的程式碼了,的確是我要的效果,感謝您!

    2018年3月30日 上午 12:18
  • Mystic Lin 先進您好!小弟不才,還有一個問題想要請教,

    延續之前的程式,現在執行起來只要我們按下button1按鍵,

    table的資料就會往下堆疊,但是如果我想要改成每當按下button1按鍵,

    資料都是從第0 Row開始,要如何撰寫會比較好?(每次都只更新Row0.Row1.Row2)

    我的想法是在按鍵一按下去之後就設定他從第0 Row開始,

    可是我try了半天就是找不到如何設定dataGrindView的Row的位置指令,

    再請Mystic Lin先進指導一下了,感謝



    2018年4月3日 上午 12:04
  • Mystic Lin 先進您好!小弟不才,還有一個問題想要請教,

    延續之前的程式,現在執行起來只要我們按下button1按鍵,

    table的資料就會往下堆疊,但是如果我想要改成每當按下button1按鍵,

    資料都是從第0 Row開始,要如何撰寫會比較好?(每次都只更新Row0.Row1.Row2)

    我的想法是在按鍵一按下去之後就設定他從第0 Row開始,

    可是我try了半天就是找不到如何設定dataGrindView的Row的位置指令,

    再請Mystic Lin先進指導一下了,感謝



    猜測你應該是忽略了上面有一個 .Add(),這會導致一直新增 row,其實只要去掉 Add,將 rowIndex 改為適當的數值即可~

    具體是這樣做的,先把 Add 這件事給移到 Form_Load 的 event~

    private List<ValueSet> _valueSets = new List<ValueSet>();
    
    private void button1_Click(object sender, EventArgs e)
    {
    	for (int rowIndex = 0; rowIndex < dataGridView1.RowCount-1 ; rowIndex++)
    	{
    		dataGridView1[Column1.Index, rowIndex].Value = _valueSets[rowIndex].MeasureValue.ToString();
    		dataGridView1[Column2.Index, rowIndex].Value = _valueSets[rowIndex].StandardValue.ToString();
    		dataGridView1[Column3.Index, rowIndex].Value = _valueSets[rowIndex].MaxValue.ToString();
    		dataGridView1[Column4.Index, rowIndex].Value = _valueSets[rowIndex].MinValue.ToString();
    	}
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
    	_valueSets.Add(new ValueSet {MeasureValue = 1, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
    	_valueSets.Add(new ValueSet {MeasureValue = 2, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
    	_valueSets.Add(new ValueSet {MeasureValue = 3, StandardValue = 0.1, MaxValue = 0.01, MinValue = -0.01});
    
    	foreach (var valueSet in _valueSets)
    	{
    		dataGridView1.Rows.Add();
    	}
    }

    希望這是你要的~

    2018年4月3日 上午 02:31
  • Mystic Lin先進您好,您修改的這個方式的確是我想要的,

    只是我有幾個疑問想要請教,

    Q1:private void Form_Load(object sender,EventArgs e)

          他只是執行一次對吧,然後利用foreach先將資料表格建立出來嗎?

    Q2:

    private List<ValueSet> _valueSets = new List<ValueSet>();

    這個片段程式是將List宣告為私人提供給button1與 Form_Load用嗎?

    Q3:我之前也是有想到用FOR迴圈來作,可是我的想法不對,我將它放在foreach內,

    他當一執行的時候就會發生錯誤,我想請教先進,有甚麼書籍還是甚麼方法可以訓練

    出像你一樣的程式概念?還是單純我對程式的用法與概念不清楚?

    麻煩您了,感謝!

    2018年4月6日 上午 02:33
  • Mystic Lin先進您好,您修改的這個方式的確是我想要的,

    只是我有幾個疑問想要請教,

    Q1:private void Form_Load(object sender,EventArgs e)

          他只是執行一次對吧,然後利用foreach先將資料表格建立出來嗎?

    是的,但嚴格來說這個步驟只是把 row 給一一新增出來,表格在這之前就已經出來了。

    Q2:

    private List<ValueSet> _valueSets = new List<ValueSet>();

    這個片段程式是將List宣告為私人提供給button1與 Form_Load用嗎?

    
    

    提供給 button1 使用沒錯~ 但嚴格來說並不是「私人提供給」 button1 而已,而是在 class Form1 當中都可以使用~

    是屬於整個 Form1 的 private 變數,其他的 class 無法存取。

    Q3:我之前也是有想到用FOR迴圈來作,可是我的想法不對,我將它放在foreach內,

    他當一執行的時候就會發生錯誤,我想請教先進,有甚麼書籍還是甚麼方法可以訓練

    出像你一樣的程式概念?還是單純我對程式的用法與概念不清楚?

    麻煩您了,感謝!

    嗯...用 FOR 與否一定不會是這個問題的癥結點,那只是一種程式語法。單單藉由這個問題我想我不太能知道你的問題點可能在哪,只能提供您一些簡單的建議~

    或許可能只是對於 DataGridView 這個元件不夠熟悉而已。我建議您可以仔細看看一執行就發生「錯誤」的錯誤訊息,嘗試用錯誤訊息去推導可能的錯誤原因,不要只用 try and error,以下是一個推導的思考方式給您參考:

    1. 猜測您所謂的錯誤應該是發生在執行「dataGridView1[xxx, yyy].Value = zzz」時發生 「An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll  Additional information: 索引超出範圍。必須為非負數且小於集合的大小。」 的錯誤訊息

    2. 看到上述的「索引超出範圍」,就可能是任何索引變數超出了範圍,例如一個陣列只有 5 的大小,卻要存取第 7 個。就會發生這樣的例外錯誤,所以就會研判 [xxx, yyy] 應該有其中一個超出了範圍。

    3. 在寫程式時,鍵入 dataGridView1[ 就會跳出一個提示視窗,說明 [int columnIndex, int rowIndex](這個上 MSDN 查也有),所以知道 xxx 應該是表示 columnIndex; yyy 是表示 rowIndex,這時就可以思考一下是哪個可能超出了範圍。

    4. 再執行一次程式,在程式跳出錯誤訊息時,把滑鼠指到 dataGridView1 的變數,會跑出一個偵錯的視窗,可以瀏覽各項屬性,這時候檢查一下 ColumnCount 及 RowCount,再和 xxx, yyy 比較一下就可以知道是哪個變數造成錯誤,會發現應該是 yyy 超出了範圍。

    5. 超出範圍的原因是 RowCount 為 0,但卻要存取 0 以上的 RowIndex,所以造成了例外錯誤狀況。接著就會想到應該要先將 row 給 Add 出來,且只要 Add 一次。而 WinForm 上只要做一次的 UI 行為,我一般會放在 FormLoad 的事件裡頭處理。

    我的思考脈落大概會是這樣,寫起來很多,但是熟練了只是一瞬間的思考過程。

    給您做參考,希望有幫助到您~

    2018年4月6日 上午 11:32
  • Mystic Lin先進,真是太感謝您耐心與詳細的解說了,

                         每每跟您討論又讓我增進不少觀念,

                         真的是很感謝您!

    2018年4月9日 上午 12:32