Solution 內有多個專案,都是在 Solution 選項內去進行變更
上課時看老師操作,才發現 Project 右鍵內,就可快捷功能可以直接設定
起始專案的名稱會有粗體的效果來提供辨識
星期五, 8月 28, 2015
[C#] DataGridView 匯出 Excel
論壇問題 - 把 DataGridView 內資料匯出 Excel
Employ Class
WinForm C# Demo
但在 dotNet 4.5 參數有預設值 Type.Missing,那表示就不用輸入啦,^^
Employ Class
namespace DataGridView2Excel
{
public class Employ
{
public string EmpNO { get; set; }
public string EmpName { get; set; }
public DateTime Birthday { get; set; }
public decimal Salary { get; set; }
}
}
WinForm C# Demo
using Excel = Microsoft.Office.Interop.Excel;
namespace DataGridView2Excel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = GetSource();
}
private List<Employ> GetSource()
{
List<Employ> source = new List<Employ>();
source.Add(new Employ() { EmpNO = "001", EmpName = "張三", Birthday = new DateTime(1970, 1, 1), Salary = 55000 });
source.Add(new Employ() { EmpNO = "002", EmpName = "李四", Birthday = new DateTime(1981, 11, 11), Salary = 35000 });
source.Add(new Employ() { EmpNO = "003", EmpName = "王五", Birthday = new DateTime(1985, 7, 7), Salary = 25000 });
return source;
}
private void btnExcel_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();
save.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
save.FileName = "Excel Export demo";
save.Filter = "*.xlsx|*.xlsx";
if (save.ShowDialog() != DialogResult.OK) return;
// Excel 物件
Excel.Application xls = null;
try
{
xls = new Excel.Application();
// Excel WorkBook
Excel.Workbook book = xls.Workbooks.Add();
// Excel WorkBook,預設會產生一個 WorkSheet,索引從 1 開始,而非 0
// 寫法1
Excel.Worksheet Sheet = (Excel.Worksheet)book.Worksheets.Item[1];
// 寫法2
Excel.Worksheet Sheet = (Excel.Worksheet)book.Worksheets[1];
// 寫法3
Excel.Worksheet Sheet = xls.ActiveSheet;
// 把 DataGridView 資料塞進 Excel 內
DataGridView2Excel(Sheet);
// 儲存檔案
book.SaveAs(save.FileName);
}
catch (Exception)
{
throw;
}
finally
{
xls.Quit();
}
}
private void DataGridView2Excel(Excel.Worksheet Sheet)
{
// 下面方法二選一使用
// 利用 DataGridView
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
string value = dataGridView1[j, i].Value.ToString();
Sheet.Cells[i + 1, j + 1] = value;
}
}
// 利用 List<Employ>
List<Employ> empList = (List<Employ>)dataGridView1.DataSource;
foreach (Employ emp in empList)
{
int
rowindex = empList.IndexOf(emp) + 1,
colindex = 1;
Sheet.Cells[rowindex, colindex++] = emp.EmpNO;
Sheet.Cells[rowindex, colindex++] = emp.EmpName;
Sheet.Cells[rowindex, colindex++] = emp.Birthday;
Sheet.Cells[rowindex, colindex++] = emp.Salary;
}
}
}
}
- Type.Missing
但在 dotNet 4.5 參數有預設值 Type.Missing,那表示就不用輸入啦,^^
- 參考資料
- 論壇討論
- 如何:以程式設計方式建立新活頁簿
- 如何:以程式設計方式列出活頁簿中的所有工作表
- Workbook.SaveAs 方法
- 王者歸來 C# 完全開發範例集 範例 342
星期四, 8月 27, 2015
[C#] Microsoft.Office.Interop.Excel - dll 引用
想學習一下,如何在 C# 中使用 Excel Automation,沒想到光是要把它加入參考,就花掉不少時間,最後是在下圖的位置,找到 Excel.dll,Orz
自己筆電
在公司電腦是在參考管理員 => 組件 => 擴充功能下就找到啦
自己筆電
在公司電腦是在參考管理員 => 組件 => 擴充功能下就找到啦
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Excel.Application demo = new Excel.Application();
}
}
}
- 參考資料
- 如何:安裝 Office 主要 Interop 組件
- Office 主要 Interop 組件
- [C#.NET][VB.NET] 如何引用 不同的命名空間 有 相同的成員名稱
- 論壇討論 => 在很多不同的位置找到該 dll,大家的經驗都不同
星期三, 8月 26, 2015
[C#] ComboBox 多欄位 - DrawItem
利用 ComboBox DrawItem Event 來作到多欄位顯示功能
DateSelect Class
DateSelect Class
namespace ComboBoxMultiCols
{
public class DateSelect
{
public int Year { get; set; }
public int TWYear { get; set; }
public static List<DateSelect> DataFill()
{
List<DateSelect> result = new List<DateSelect>();
DateTime
Today = DateTime.Today ,
LoopDate = DateTime.Today ;
int
Year = 0 ,
TWYear = 0;
System.Globalization.TaiwanCalendar tc = new System.Globalization.TaiwanCalendar();
for (int i = 0; i < 10; i++)
{
LoopDate = Today.AddYears(i * -1);
Year = LoopDate.Year;
TWYear = tc.GetYear(LoopDate);
DateSelect ds = new DateSelect()
{
Year = Year ,
TWYear = TWYear
};
result.Add(ds);
}
return result;
}
}
}
WinForm Demonamespace ComboBoxMultiCols
{
public partial class MultiCols_DrawItem : Form
{
public MultiCols_DrawItem()
{
InitializeComponent();
}
private void MultiCols_DrawItem_Load(object sender, EventArgs e)
{
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.DataSource = DateSelect.DataFill();
comboBox1.DisplayMember = "Year";
comboBox1.ValueMember = "TWYear";
comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
comboBox1.DrawItem += comboBox1_DrawItem;
}
void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
// 繪製預設背景
e.DrawBackground();
// DataSource 是 List<DateSelect>,所以這裡必須轉型為 DateSelect
// 假如 DataSource 是 DataTable,就必須轉型為 DataRowView
DateSelect ds = (DateSelect)this.comboBox1.Items[e.Index];
// ComboBox 內文字
string DropDownInfo = string.Format("{0} (民國 {1:000} 年)", ds.Year, ds.TWYear);
// 取得 ComboBox 界限
Rectangle rec = e.Bounds;
// 把文字繪進去
using (SolidBrush sb = new SolidBrush(e.ForeColor))
{
e.Graphics.DrawString(DropDownInfo, e.Font, sb, rec);
}
}
}
}
星期二, 8月 25, 2015
星期一, 8月 24, 2015
[C#] ComboBox 多欄位 - TSQL
在 T-SQL 中先行把 ComboxBox DisplayMember 的資料整理好,藉此來作到多欄位顯示功能
利用該 Store Procedure 來產生日期資料
利用該 Store Procedure 來產生日期資料
CREATE PROCEDURE dbo.GetComboBoxData
AS
BEGIN
WITH CTE AS
(
SELECT
YEAR(GetDate()) AS [Year] , 0 AS DelCount
UNION ALL
SELECT
[Year] - 1 , DelCount + 1
FROM CTE
WHERE DelCount + 1 <= 10
)
SELECT
CAST([Year] AS varchar(4)) +
'( 民國 ' + RIGHT(REPLICATE('0',3) + CAST([Year] - 1911 AS varchar(3)),3) + ' 年)' AS Display ,
[Year] AS value
FROM CTE
END
C# Winform 中的測試 Code using System.Data.SqlClient;
namespace ComboBoxMultiCols
{
public partial class MultiCols_TSQL : Form
{
public MultiCols_TSQL()
{
InitializeComponent();
}
private void MultiCols_TSQL_Load(object sender, EventArgs e)
{
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
SetComboDaataSource();
}
private void SetComboDaataSource()
{
string ConnString = @"Data Source=InstanceName;Initial Catalog=DBName;Integrated Security=True";
using(SqlConnection conn = new SqlConnection(ConnString))
{
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetComboBoxData";
if (conn.State == ConnectionState.Closed) conn.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(dt);
comboBox1.DataSource = dt;
comboBox1.DisplayMember = dt.Columns[0].ToString();
comboBox1.ValueMember = dt.Columns[1].ToString();
}
catch (Exception)
{
throw;
}
}
}
}
}
- 參考資料
- 論壇討論
星期五, 8月 21, 2015
[C#] ComboBox 多欄位 - Format
利用 ComboBox Format Event 來作到多欄位顯示功能
DateSelect Class
WinForm Demo
DateSelect Class
namespace ComboBoxMultiCols
{
public class DateSelect
{
public int Year { get; set; }
public int TWYear { get; set; }
public static List<DateSelect> DataFill()
{
List<DateSelect> result = new List<DateSelect>();
DateTime
Today = DateTime.Today ,
LoopDate = DateTime.Today ;
int
Year = 0 ,
TWYear = 0;
System.Globalization.TaiwanCalendar tc = new System.Globalization.TaiwanCalendar();
for (int i = 0; i < 10; i++)
{
LoopDate = Today.AddYears(i * -1);
Year = LoopDate.Year;
TWYear = tc.GetYear(LoopDate);
DateSelect ds = new DateSelect()
{
Year = Year ,
TWYear = TWYear
};
result.Add(ds);
}
return result;
}
}
}
WinForm Demo
namespace ComboBoxMultiCols
{
public partial class MultiCols_Format : Form
{
public MultiCols_Format()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.DataSource = DateSelect.DataFill();
comboBox1.DisplayMember = "TWYear";
comboBox1.ValueMember = "Year";
}
private void comboBox1_Format(object sender, ListControlConvertEventArgs e)
{
DateSelect ds = e.ListItem as DateSelect;
if (ds == null) return;
e.Value = string.Format("{0} (民國{1})",ds.Year,ds.TWYear.ToString("000"));
}
}
}
星期四, 8月 20, 2015
[C#] Reflection - Property
看見這篇文章標題 How to Get Name of the Member (Property Name, etc.) of a .NET Class Without Using Hard-coded/ Magic Strings,原以為是介紹 Reflection,看完內容才知道還可以用 System.Linq.Expressions 來達到相同效果
紀錄 Reflection 的作法
City Class
紀錄 Reflection 的作法
City Class
namespace ReflectionProperty { public class City { public int CityId { get; set; } public string CityName { get; set; } } }Program.cs Code
using System.Reflection; namespace ReflectionProperty { class Program { static void Main(string[] args) { // 抓 Type 的 3 種方法 // 方法1:System.Object.GetType() City c = new City(); Type t = c.GetType(); // 方法2:Type.GetType() Type t = Type.GetType("ReflectionProperty.City"); // 方法3: Typeof() Type t = typeof(City); if (t == null) { Console.WriteLine("找不到 Type"); return; } Console.WriteLine(string.Format("Type FullName:{0}",t.FullName)); // 利用 Type.GetProperties() 來抓 Property PropertyInfo[] pis = t.GetProperties(); foreach (PropertyInfo pi in pis) { Console.WriteLine(string.Format("Property Name:{0}", pi.Name)); } } } }
星期二, 8月 18, 2015
[ZWCAD] 啟動問題
幫新電腦安裝 ZWCAD 時,註冊時發現,怎麼序號驗證後,竟然載入莫名其妙的公司資訊,直覺有問題,馬上 PrintScreen 存檔留下證據,Google 該公司行號,還真的存在,
老大致電客服,客服也沒有給出很明確的解決方案,不知道使用一段時間後會發生甚麼事情,哈
老大致電客服,客服也沒有給出很明確的解決方案,不知道使用一段時間後會發生甚麼事情,哈
星期日, 8月 16, 2015
[C#] 重複字元
閱讀該教學影片時 小山的 C# 教學-第13課-NumericUpDown,看見作者用雙迴圈產生星號時,原想說用 T-SQL Replicate() 函數就可以用單迴圈,沒想到 C# 沒有對應 Replicate() 的函數,Orz
Project 檔案
Winform 畫面
把 Relpicate() 函數寫成擴充事件來使用
一個突發奇想,讓自己的函式庫內又多一個擴充事件,^^
Project 檔案
Winform 畫面
把 Relpicate() 函數寫成擴充事件來使用
namespace NumericUpDown { public static class ExtChar { public static string Replicate(this char value , int count) { // 輸入負值或 0,就把 char 回傳 count = Math.Max(count,1); return new string(value,count); } } }C# Code
namespace NumericUpDown { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnRun_Click(object sender, EventArgs e) { // numericUpDonw.Value property 回傳值是 decimal int count = (int)numericUpDown1.Value; // 輸入 0 或負值,就跑一次就好 count = Math.Max(count, 1); char sign = '*' ; lblResult.Text = string.Empty; for (int i = 1; i <= count; i++) { lblResult.Text += string.Concat(sign.Replicate(i), Environment.NewLine); } } } }執行結果
一個突發奇想,讓自己的函式庫內又多一個擴充事件,^^
- 參考資料
- 小山的 C# 教學-第13課-NumericUpDown
- Best way to repeat a character in C#
- ASP.NET 3.5 圖表與實務案例模組大全 P14-8
星期五, 8月 14, 2015
[C#] MaskedTextBox
實作這篇 MSDN 文章 逐步解說:使用 MaskedTextBox 控制項
測試 1:空值
測試 2:嘗試輸入中文
測試 3:輸入無效日期
namespace maskedTextBoxMSDN
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// 設定西元簡單日期
maskedTextBox1.Mask = "0000/00/00";
// 發出系統警示音
maskedTextBox1.BeepOnError = true;
// 欲驗證資料型態
maskedTextBox1.ValidatingType = typeof(DateTime);
// 註冊事件
maskedTextBox1.MaskInputRejected += maskedTextBox1_MaskInputRejected;
maskedTextBox1.TypeValidationCompleted += maskedTextBox1_TypeValidationCompleted;
}
void maskedTextBox1_TypeValidationCompleted(object sender, TypeValidationEventArgs e)
{
if (e.IsValidInput) return;
toolTip1.ToolTipTitle = "TypeValidationCompleted Event";
toolTip1.Show(e.Message, maskedTextBox1, 5000);
// 取消該事件,並把 focus 鎖定在 maskedTextbox
e.Cancel = true;
}
void maskedTextBox1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
{
toolTip1.ToolTipTitle = "MaskInputRejected Event";
toolTip1.Show(e.RejectionHint.ToString(), maskedTextBox1, 5000);
}
}
}
測試 1:空值
測試 2:嘗試輸入中文
測試 3:輸入無效日期
星期日, 8月 09, 2015
[C#] MonthCalendar
了解 WinForm 內鍵的 MonthCalendar 時,發現該控件使用彈性不高。
根據預設,Windows XP 會提供一種新的視覺化樣式。 當 Windows Form 在 Windows XP 中執行時,表單上的捲軸和標題列都會自動使用新的視覺化樣式。 如果應用程式呼叫 EnableVisualStyles 方法,而且應用程式是在 Windows XP 中執行,則大部分的 Windows Form 控制項都會自動使用這個視覺化樣式。
- MSDN Windows XP 視覺化樣式 說明
根據預設,Windows XP 會提供一種新的視覺化樣式。 當 Windows Form 在 Windows XP 中執行時,表單上的捲軸和標題列都會自動使用新的視覺化樣式。 如果應用程式呼叫 EnableVisualStyles 方法,而且應用程式是在 Windows XP 中執行,則大部分的 Windows Form 控制項都會自動使用這個視覺化樣式。
- 開啟/關閉 Windows XP 視覺化樣式
- 問題點 1:關閉 XP 視覺化,顏色相關設定才會出現,左圖關閉、右圖開啟
- 問題點 2:開啟 XP 視覺化,MinDate 和 MaxDate 設定值,才會被凸顯,左圖關閉、右圖開啟
- 參考資料
- 如何:啟用 Windows XP 視覺化樣式
- WinForms User Control for date selection => DataGridView 應用
- Customizable MonthCalendar Type Control: Part 1 => PictureBox 應用
- Customizable MonthCalendar Type Control: Part 2 => 行事曆
- Another Month Calendar => MonthCalendar 應用
- MonthCalendar Calendar - Control => MonthCalendar 應用
星期五, 8月 07, 2015
[SQL] 錯誤訊息 8623
一大早開 mail 就被嚇到,這是甚麼錯誤訊息,Orz
錯誤訊息
2009 年的 Connect 回報,The query processor ran out of internal resources and could not produce a query plan with WHERE in and several thousand values,根據官方回答,看來是要無解啦
後來詢問同事(就兩個人寫 ERP,很容易找出兇手,哈),同事有提到是用 UNION ALL 去串接資料產生這個錯誤訊息,發現後就馬上改掉 T-SQL 語法,雖然跟查到資料的方向都不太一樣,但看來這個 Error 應該是不會在出現才對
錯誤訊息
The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.根據這篇官方文章 FIX: Error message when you run a complex query after you install Cumulative Update 3 or Cumulative Update 4 for SQL Server 2005 Service Pack 2: "The query processor ran out of internal resources and could not produce a query plan" ,是說明 SP2 的 CU3 或 CU4 就已經修正,我們是 SP4 了,Orz
2009 年的 Connect 回報,The query processor ran out of internal resources and could not produce a query plan with WHERE in and several thousand values,根據官方回答,看來是要無解啦
後來詢問同事(就兩個人寫 ERP,很容易找出兇手,哈),同事有提到是用 UNION ALL 去串接資料產生這個錯誤訊息,發現後就馬上改掉 T-SQL 語法,雖然跟查到資料的方向都不太一樣,但看來這個 Error 應該是不會在出現才對
- 參考資料
- FIX: Error message when you run a complex query after you install Cumulative Update 3 or Cumulative Update 4 for SQL Server 2005 Service Pack 2: "The query processor ran out of internal resources and could not produce a query plan"
- The query processor ran out of internal resources and could not produce a query plan with WHERE in and several thousand values
- Using Server Trace to Identify 8623 Errors => 這篇提及是 IN (...) 太多參數造成的
星期四, 8月 06, 2015
[Win] 檔案關聯
同事跑來說 PC 中毒啦,要我趕快去看,當下聽到中毒,是一整個囧,聽完案發事件的前因後果,鬆了一口氣,^^ ~~
同事間利用 Skype 傳送檔案,但沒有傳實際檔案,而是傳檔案捷徑過來,接收者打開該捷徑後,發現無法開啟且全部程式,竟然都無法執行,其實是全部的捷徑,通通都用 Adobe Reader 來開啟,可能該捷徑是 PDF 的關係吧,請教 Google 大神就發現到,這還不是單一事件,網路上也有相同案例,解決方式是要解除捷徑的檔案關聯
利用 A Utility to Unassociate File Types in Windows 7 and Vista 這套小軟體來解除關聯,在搜尋視窗內輸入 lnk 後,再按 "Remove File association (User)" 按鈕就行
不用重開機就回復正常
同事間利用 Skype 傳送檔案,但沒有傳實際檔案,而是傳檔案捷徑過來,接收者打開該捷徑後,發現無法開啟且全部程式,竟然都無法執行,其實是全部的捷徑,通通都用 Adobe Reader 來開啟,可能該捷徑是 PDF 的關係吧,請教 Google 大神就發現到,這還不是單一事件,網路上也有相同案例,解決方式是要解除捷徑的檔案關聯
利用 A Utility to Unassociate File Types in Windows 7 and Vista 這套小軟體來解除關聯,在搜尋視窗內輸入 lnk 後,再按 "Remove File association (User)" 按鈕就行