2008年11月14日 星期五

網路收音機 Ver 0.6

愛用 Hinet 網路收音機聽廣播的朋友們,請試試這個小程式

主視窗
01
主視窗的工具列由左而右是:
頻道選擇、透明度滑桿、關於此程式、切換顯示媒體播放器介面、隱藏主視窗

隱藏收音機介面之後,是這樣的
02

工具列圖示
03

工具列選單
04

關於此程式
05

要換頻道,可以從主視窗選擇,也可以從工具列選單的「頻道」去選擇 要結束,請從工具列選單選擇「離開」 程式關閉時,會記住:

  1. 上次聽的頻道
  2. 收音機介面是否隱藏
  3. 主視窗是否隱藏
  4. 透明度
  5. 視窗位置
手動增加頻道方法:
  1. 增加頻道供應者
    這部份存放在 WebRadio.xml 的 <URLS> 與 </URLS> 之間,每一個頻道供應者是一個 <URL> 標籤,裡面有兩個屬性:ID 與 URL
    附上的檔案,除了 Hinet 之外,還有 difm 與 skyfm 兩家網路頻道供應者 如果要自行增加其他頻道供應者的話,請依照以下原則
    ● ID 是這個頻道供應者的 ID,你可以自己取名字,但不可以重複
    ● URL 是收聽連結的固定部份,要依照實際狀況而定
    以 difm 為例,difm 的收聽連結是這樣的:http://www.di.fm/wma/xxxxx.asx 變動的部份只有 xxxxx.asx ,而 http://www.di.fm/wma/ 是不變的,所以 URL 屬性的值就是 http://www.di.fm/wma/
  2. 增加頻道資料
    這部份存放在 WebRadio.xml 的 <CHANNELS> 與 </CHANNELS> 之間,每一個頻道是一個 <CHANNEL> 標籤,裡面有四個屬性:ID、TEXT、URLID、SUBID
    ● ID 是這個頻道的編號,不可以重複
    ● TEXT 是這個頻道的名字
    ● URLID 是這個頻道的供應者 ID
    ● SUBID 是收聽連結的變動部份
    以 <CHANNEL ID="difm.electro" TEXT="Electro House" URLID="difm" SUBID="electro.asx"/> 這一行為例
    ● ID="difm.electro" 這是自己取的 ID
    ● TEXT="Electro House" 這是頻道的名字
    ● URLID="difm" 這是頻道供應者的ID,用這個ID取得收聽連結的固定部份
    ● SUBID="electro.asx" 這是收聽連結的變動部份

歡迎給予本人意見。謝謝指教! 下載連結

2008年10月24日 星期五

使用 XPath 對 XML文件做模糊查詢

XML 第一種儲存方式,使用 Node 來儲存資料
<users>
<user>
   <username>huo</username>
   <password>123</password>
   <createtime>2008-06-17</createtime>
</user>
</users>

xPath查詢如:
等值查詢:
String xPath = "users/user[username='huo' and password='123']";
模糊查詢:
String xPath = "users/user[contains(username,'huo') and contains(password,'123')]";

 

XML第二種儲存方式,使用 Attribute 來儲存資料

<users>
<user username="huo" password="123" createtime="2008-06-17" />
</users>

xPath查詢如:加 "@" 用以查詢屬性值
等值查詢:
String xPath = "users/user[@username='huo' and @password='123']";
模糊查詢:
String xPath = "users/user[contains(@username,'huo') and contains(@password,'123')]";

2008年9月19日 星期五

取得觸發 PostBack 的控制項 ID以及用 Javascript 觸發 PostBack 動作

用 Request[Page.postEventSourceID] 可以取得觸發 PostBack 的控制項 ID
而用 __doPostBack('控制項ID','command argument'); 這一行 Javascript 就可以觸發 PostBack

2008年9月8日 星期一

數字轉中式大寫的 Crystal Report 公式

//=========================================
// 數字轉中文大寫
//=========================================

// 要轉換的數字
NumberVar VNT := (你要轉換的數字欄位); 
StringVar VSU := '零壹貳參肆伍陸柒捌玖'; 
StringVar VST := '仟佰拾兆仟佰拾億仟佰拾萬仟佰拾元'; 
StringVar VNS := ToText(VNT, '0000000000000000'); 
NumberVar VSL := 17 - Length(TrimLeft(ToText(VNT, '################'))); 
StringVar VSS := ''; 
BooleanVar VSF; 
BooleanVar VS0; 
BooleanVar VS1; 
BooleanVar VS2; 
NumberVar VNI; 

VSF := False; 
for VNI := VSL to 16 do 
( 
  VS1 := Mid(VNS, VNI, 1) <> '0'; 
  VS2 := VS1 or (((VNI mod 4) = 0) and ((Mid(VNS, VNI - 3, 4) <> '0000') or (VNI = 16))); 
  VS0 := VSF and VS1; 
  VSF := not (VS0 or VS1 or VS2); 
  if VS0 then 
    VSS := VSS + '零'; 
  if VS1 then 
    VSS := VSS + Mid(VSU, ToNumber(Mid(VNS, VNI, 1)) + 1, 1); 
  if VS2 then 
    VSS := VSS + Mid(VST, VNI, 1); 
); 
// 這是回傳值
VSS;

2008年7月4日 星期五

詐砲的自訂公式

假如客戶要求你,某一個計算公式可以讓他自由設定,你想要怎麼做?
例如:加班費計算
有些人想要 ROUND(時薪 * 加班費比例) * 時數
有些人想要 FLOOR(時薪 * 加班費比例) * 時數
有些人想要 ROUND(時薪 * 加班費比例 * 時數)
有些人想要 FLOOR(時薪 * 加班費比例 * 時數)

於是就有程式人員這樣寫啦
switch(計算方式)
{
case "1" :
 加班費 = ROUND(時薪 * 加班費比例) * 時數;
 break;
case "2" :
 加班費 = FLOOR(時薪 * 加班費比例) * 時數;
 break;
case "3" :
 加班費 = ROUND(時薪 * 加班費比例 * 時數);
 break;
case "4" :
 加班費 = FLOOR(時薪 * 加班費比例 * 時數);
 break;
}
第五種狀況出現時怎麼辦?改程式?寫程式一定要這樣歹命嗎?
來!我有一個詐砲方法給大家參考
就是請資料庫伺服器幫你算!
以 SQL Server 為例子

SELECT ROUND(@時薪 * @加班費比例, 0) * @時數

只要把 @時薪、@加班費比例、@時數 三個參數丟進去,就有計算結果啦
所以呢,「ROUND(@時薪 * @加班費比例, 0) * @時數」這一串文字就可以變成「加班費計算公式」的設定
反正加班費再怎麼算,都脫離不了時薪、加班費比例、時數三個參數

我覺得這個方法相當不錯,提供您參考喔~~

2008年6月17日 星期二

C# 使用 ADOX 建立新 Table

有時,需要把資料匯出到 MDB 裡面,但是在 ADO.Net 中沒有建立 MDB 以及在 MDB 中建立 Table 的功能 (create table 的 SQL 敘述除外)。
所以,有必要撰寫這樣的工具程式,以便於後續方便使用

使用 ADO 以及 ADOX 之前,要加入兩個 COM 的參考
  1. C:\Program Files\Common Files\System\ado\msado15.dll (ADODB)
  2. C:\Program Files\Common Files\System\ado\msadox.dll (ADOX)
這兩個 COM 加進來之後,命名空間如括弧內所示
接下來,撰寫程式如下

/// <summary>
/// 建立 MDB 資料庫以及資料表
/// </summary>
public class MDBCreate
{
  private ADOX.CatalogClass catalog = new ADOX.CatalogClass();
  private ADODB.Connection connection = new ADODB.ConnectionClass();
  private string createConnStr =
    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}";
  private string _fileName = "";

  /// <summary>
  /// MDB 檔案名稱
  /// </summary>
  public string FileName
  {
    get
    {
      return _fileName;
    }
    set
    {
      _fileName = value;

    }
  }

  /// <summary>
  /// 建立新的 MDB 資料庫
  /// </summary>
  /// <param name="deleteIfExist">是否刪除現有的</param>
  /// <returns>是否建立成功</returns>
  public bool CreateMDB(bool deleteIfExist)
  {
    try
    {
      if (deleteIfExist)
      {
        if (File.Exists(_fileName))
          File.Delete(_fileName);
      }
      catalog.Create(String.Format(createConnStr, _fileName));
      return true;
    }
    catch
    {
      return false;
    }
  }

  /// <summary>
  /// 利用 DataTable 結構,於 MDB 檔案中建立新的 Table
  /// </summary>
  /// <param name="tableName">Table 名稱</param>
  /// <param name="sourceTable">包含表格結構的 DataTable 執行個體</param>
  /// <returns>是否建立成功</returns>
  public bool CreateTable(string tableName, DataTable sourceTable)
  {
    string connStr = String.Format(createConnStr, _fileName) + ";Persist Security Info=False";
    connection.Open(connStr, "", "", 0);
    catalog.ActiveConnection = connection;

    ADOX.TableClass table = new TableClass();
    ADOX.DataTypeEnum fieldType = ADOX.DataTypeEnum.adWChar;
    int fieldLength = 0;

    table.Name = tableName;

    for (int i = 0; i < sourceTable.Columns.Count; i++)
    {
      DataColumn column = sourceTable.Columns[i];

      switch (column.DataType.FullName)
      {
        case "System.Boolean":
          fieldType = ADOX.DataTypeEnum.adBoolean;
          break;
        case "System.Byte":
          fieldType = ADOX.DataTypeEnum.adUnsignedTinyInt;
          break;
        case "System.Char":
          fieldType = ADOX.DataTypeEnum.adWChar;
          fieldLength = column.MaxLength;
          if (fieldLength == -1)
            fieldLength = 255;
          break;
        case "System.DateTime":
          fieldType = ADOX.DataTypeEnum.adDate;
          break;
        case "System.Decimal":
          fieldType = ADOX.DataTypeEnum.adCurrency;
          break;
        case "System.Double":
          fieldType = ADOX.DataTypeEnum.adDouble;
          break;
        case "System.Int16":
          fieldType = ADOX.DataTypeEnum.adSmallInt;
          break;
        case "System.Int32":
          fieldType = ADOX.DataTypeEnum.adInteger;
          break;
        case "System.Int64":
          fieldType = ADOX.DataTypeEnum.adInteger;
          break;
        case "System.SByte":
          fieldType = ADOX.DataTypeEnum.adSmallInt;
          break;
        case "System.Single":
          fieldType = ADOX.DataTypeEnum.adSingle;
          break;
        case "System.String":
          // 因為 MDB 檔的文字欄位最大長度是 255
          // 所以超過時,以 memo 欄位存放
          if (column.MaxLength > 255)
          {
            fieldType = ADOX.DataTypeEnum.adLongVarWChar;
            fieldLength = 0;
          }
          else
          {
            fieldType = ADOX.DataTypeEnum.adVarWChar;
            fieldLength = column.MaxLength;
            if (fieldLength == -1)
              fieldLength = 255;
          }
          break;
        case "System.UInt16":
          fieldType = ADOX.DataTypeEnum.adSmallInt;
          break;
        case "System.UInt32":
          fieldType = ADOX.DataTypeEnum.adInteger;
          break;
        case "System.UInt64":
          fieldType = ADOX.DataTypeEnum.adInteger;
          break;
        case "System.Byte[]":
          fieldType = ADOX.DataTypeEnum.adLongVarBinary;
          break;
      }

      // 將新增的欄位物件加入 Table 中,並設定欄位屬性為可 null
      table.Columns.Append(column.ColumnName, fieldType, fieldLength);
      table.Columns[i].Attributes = ColumnAttributesEnum.adColNullable;
    }

    try
    {
      // 將新增的 Table 物件加入 Catalog 物件,以達到建立新 Table 的目的
      catalog.Tables.Append(table);
      catalog.ActiveConnection = null;
      return true;
    }
    catch
    {
      return false;
    }
    finally
    {
      connection.Close();
    }
  }
}