星期一, 2月 23, 2015

[C#] Delegate 練習

遠距教學提到可以透過 delegate 把 Method 當成參數傳進 Method 中,故意拿勞保費計算來練習 delegate

畫面控件
  • 勞保投保薪資:25200、33300、43900
  • 減免條件:正常、身心輕度、身心中度、極重或重

[C#] Delegate 練習-1

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
  
    }

    delegate decimal demo(decimal LSalary , decimal discount);

    class Employ
    {
        public bool Hirer { get; set; }
        
        // 計算勞保薪資
        public decimal LaborFee(decimal LSalary , decimal discount,demo func)            
        {                 
            decimal retValue = 0m;                 

            if (this.Hirer == true)                 
            {                      
                retValue = func(LSalary , discount);                 
            }                 
            else                 
            {                      
                retValue = func(LSalary, discount);                 
            }                 
            return retValue;            
        }              
      
        // 勞保計算公式 - 雇主
        public decimal LaborForHirer(decimal LSalary, decimal discount)
        {

            decimal retValue = Math.Round(LSalary * 0.09m * 0.2m, 0, MidpointRounding.AwayFromZero) -
                               Math.Round
                                   (
                                       (
                                           Math.Round(LSalary * 0.09m * 0.2m, 0, MidpointRounding.AwayFromZero) +
                                           Math.Round(LSalary * 0.2m, 0, MidpointRounding.AwayFromZero)
                                       ) * discount
                                       , 0, MidpointRounding.AwayFromZero
                                   );

            if (retValue < 0) retValue = 0;
            return retValue;
        }

        // 勞保計算公式 - 員工
        public decimal LaborForEmploy(decimal LSalary, decimal discount)
        {
            decimal retValue = Math.Round(LSalary * 0.09m * 0.2m, 0, MidpointRounding.AwayFromZero) +
                               Math.Round(LSalary * 0.01m * 0.2m, 0, MidpointRounding.AwayFromZero) -
                               Math.Round
                                   (
                                       (
                                           Math.Round(LSalary * 0.09m * 0.2m, 0, MidpointRounding.AwayFromZero) +
                                           Math.Round(LSalary * 0.01m * 0.2m, 0, MidpointRounding.AwayFromZero)
                                       ) * discount
                                       , 0, MidpointRounding.AwayFromZero
                                   );

            if (retValue < 0) retValue = 0;
            return retValue;
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        Employ emp = new Employ();
        emp.Hirer = chkHirer.Checked;
        decimal LSalary = Convert.ToDecimal(ddlLSalary.SelectedValue);

        decimal discount = 0m;
        string discountType = ddldiscountType.SelectedValue;
        switch (discountType)
        {
            case "正常":
                discount = 0m;
                break ;
            case "身心輕度":
                discount = 0.25m;
                break ;
            case "身心中度":
                discount = 0.5m;
                break ;
            case "極重或重":
                discount = 1m;
                break;
            default:
                discount = 1m;
                break;
        }

        demo func;
        if (emp.Hirer == true)
        {
            func = new demo(emp.LaborForHirer);
        }
        else
        {
            func = new demo(emp.LaborForEmploy);
        }

        lblResult.Text = string.Format("勞保費為:{0}", emp.LaborFee(LSalary, discount, func));
    }
}

顯示結果
[C#] Delegate 練習-2

星期二, 2月 17, 2015

[SQL] 管理錯誤記錄檔案

這篇記錄 xp_readerrorlog(undocumented extended stored procedure)搭配 Database Mail 檢查每天是否有錯誤訊息並發信通知
-- 宣告變數
DECLARE @text NVARCHAR(MAX)
DECLARE @ErrorLog TABLE (ID INT IDENTITY, LogDate datetime, ProcessInfo nvarchar(10),Text nvarchar(3950))
DECLARE @StartDate AS datetime
DECLARE @EndDate AS datetime
SET @StartDate = CONVERT(char(10),getdate(),120)
SET @EndDate = CONVERT(char(10),DATEADD(dd,1,getdate()),120)

-- 把 SQL Server ErrorLog 資料塞進 @ErrorLog
INSERT @ErrorLog EXEC master.dbo.xp_readerrorlog 0,1,NULL,NULL,@StartDate,@EndDate

-- 把 SQL Server Agent ErrorLog 資料塞進 @ErrorLog
INSERT @ErrorLog EXEC master.dbo.xp_readerrorlog 0,2,NULL,NULL,@StartDate,@EndDate

IF EXISTS 
    (
        SELECT 1 
        FROM @ErrorLog 
        WHERE Text LIKE N'%錯誤%' OR 
            (Text LIKE N'%Error%' AND Text NOT LIKE N'%SPN%')
    )
        BEGIN
        
            -- 整理 HTML Table 資料
            SET @text =
                N' <H1>錯誤檔案</H1>' +
                N'<table border="1">' +
                N'<tr><th>ID</th><th>LogDate</th><th>ProcessInfo</th><th>Text</th></tr>' +
                ( 
                    SELECT
                        td = ID, '' ,
                        td = LogDate, '' ,
                        td = ProcessInfo, '' ,
                        td = Text
                    FROM @ErrorLog 
                    WHERE Text LIKE N'%錯誤%' OR 
                        (Text LIKE N'%Error%' AND Text NOT LIKE N'%SPN%')
                    FOR XML PATH('tr')
                ) +
                N'</table>'

            -- 進行發信通知  
            EXEC msdb.dbo.sp_send_dbmail 
                @profile_name = 'ProfileName' ,
                @recipients = '收件人 EMail' ,
                @subject = 'SQL Server 通知 - 錯誤檔案訊息',
                @body = @text ,
                @body_format = 'HTML'

        END
故意利用 sa 登入造成登入失敗,再利用上述語法來測試是否發信成功
[SQL] 管理錯誤記錄檔案

星期一, 2月 16, 2015

[C#] IComparable 和 IComparer

這篇文章 如何使用 IComparable 和 IComparer 介面視覺 C# 內容,剛好跟遠距教學內容差依不大,拿它來進行排序練習

建立兩個 Project,分別為 ClassDemo Project 和 Show Project

[C#] IComparable 和 IComparer-1

ClassDemo Project


using System.Collections.Generic;
using System.Collections; // IComparer interface 在 System.Collections namespace 內

namespace ClassDemo
{
    public class Car
    {
        public string Maker { get; set; }
        public int Year { get; set; }
        public decimal Price { get; set; }
  
        class SortByMaker : IComparer
        {
            public int Compare(object x, object y)
            {
                Car x1 = x as Car;
                Car y1 = y as Car;
                return x1.Maker.CompareTo(y1.Maker);
            }
        }

        class SortByMakerDesc : IComparer
        {
           public int Compare(object x, object y)
           {
               Car x1 = x as Car;
               Car y1 = y as Car;
               return y1.Maker.CompareTo(x1.Maker);
           }
        }

        class SortByYear : IComparer
        {
            public int Compare(object x, object y)
            {
                Car x1 = x as Car;
                Car y1 = y as Car;
                return x1.Year.CompareTo(y1.Year);
            }
        }

        class SortByYearDesc : IComparer
        {
            public int Compare(object x, object y)
            {
                Car x1 = x as Car;
                Car y1 = y as Car;
                return y1.Year.CompareTo(x1.Year);
            }
        }

        class SortByPrice : IComparer
        {
            public int Compare(object x, object y)
            {
                Car x1 = x as Car;
                Car y1 = y as Car;
                return x1.Price.CompareTo(y1.Price);
            }
        }

        class SortByPriceDesc : IComparer
        {
            public int Compare(object x, object y)
            {
                Car x1 = x as Car;
                Car y1 = y as Car;
                return y1.Price.CompareTo(x1.Price);
            }
        }

        private static IComparer[] Sorters = new IComparer[]
        {
            new SortByMaker(),
            new SortByMakerDesc(),
            new SortByYear(),
            new SortByYearDesc(),
            new SortByPrice(),
            new SortByPriceDesc(),
        };
  
        public static IComparer 依廠牌排序
        {
            get { return Sorters[0];}
        }

        public static IComparer 依廠牌遞減排序
        {
            get { return Sorters[1]; }
        }

        public static IComparer 依年份排序
        {
            get { return Sorters[2]; }
        }

        public static IComparer 依年份遞減排序
        {
            get { return Sorters[3]; }
        }

        public static IComparer 依價格排序
        {
            get { return Sorters[4]; }
        }

        public static IComparer 依價格遞減排序
        {
            get { return Sorters[5]; }
        }

        public override string ToString()
        {
            return string.Format("{0} - {1} - {2}", this.Maker, this.Year, this.Price);
        }
    }
}

星期一, 2月 09, 2015

[C#] 利用 Interface 取控件值

根據遠距教學老師強調的重點實做,控件應實作 interface,並利用 interface 來抓取控件的值
  1. 建立 MyControl Project 並產生三個 class (MyTextBox、MyDropDownList 和 MyCheckBox),接實作 Interface (IDemo)
  2. 建立 IntertfaceDemo Project 並參考 MyControl.dll
[C#] Interface 2-1

星期二, 2月 03, 2015

[C#] ASP.NET 特殊資料夾

遠距教學時,老師加入 App_Code 資料夾並進行 code 撰寫,才發現 App_Code 不是單純的資料夾,在 ASP.NET 中是有其特殊用途的,Google 些資料來了解特殊資料夾用途

MSDN 特殊資料夾說明

資料夾說明
App_Browsers存放瀏覽器定義 (.browser 檔),ASP.NET 會使用這些檔案來辨識個別瀏覽器並判斷它們的功能
App_Code存放用於公用程式類別和商務物件 (Business Object) (例如,.cs、.vb 和 .jsl 檔案) 的原始程式碼
App_Data存放應用程式資料檔,這包括 MDF 檔案、XML 檔案和其他資料存放區檔。ASP.NET 2.0 會使用 App_Data 資料夾存放應用程式的本機資料庫,這個資料庫可用來維護成員資格和角色資訊
App_GlobalResources存放資源 (.resx 和 .resources 檔案),這些資源會編譯成具有全域範圍的組件。App_GlobalResources 資料夾中的資源是強型別的,並且可以用程式設計的方式存取
App_LocalResources存放資源 (.resx 和 .resources 檔案),這些資源會與特定的頁面、使用者控制項或應用程式的主版頁面 (Master Page) 相關聯
App_Themes存放檔案集合 (.skin 和 .css 檔案,以及影像檔與泛型資源),可定義 ASP.NET Web 網頁和控制項的外觀
App_WebReferences存放參考合約檔 (.wsdl 檔)、結構描述 (.xsd 檔) 和探索文件檔 (.disco 和 .discomap 檔)
Bin包含控制項、元件或您要在應用程式中參考之其他程式碼的已編譯組件 (.dll 檔案)。在 [Bin] 資料夾中以程式碼表示的任何類別,都會自動在應用程式中參考到

星期一, 2月 02, 2015

[Azure] VM - 靜態 IP

設定現有 VM static ip 的 PowerShell 語法紀錄。

練習環境:
  • 雲端服務:VM-IP
  • VM:VM-IP
  • 網路:VNET-IP
Step1:確認特定 ip 是可以使用的

Test-AzureStaticVNetIP –VNetName VNET-IP –IPAddress 192.168.0.10

[Azure] VM - 靜態 IP-1

Step2:進行 static ip 設定

Get-AzureVM -ServiceName VM-IP -Name VM-IP | Set-AzureStaticVNetIP -IPAddress 192.168.0.10 | Update-AzureVM

[Azure] VM - 靜態 IP-2

Step3:確認 static ip 設定

Get-AzureVM -ServiceName VM-IP -Name VM-IP | Get-AzureStaticVNetIP

[Azure] VM - 靜態 IP-3

要注意 Update-AzureVM 語法會造成 VM 重新啟動喔