Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ExcelDNASkype.csの、for二重ループをLINQで置き換えたサンプル (出力されるテキストファイルは4倍になっていることに注意)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// Add
using System.Windows.Forms;
using ExcelDna.Integration;
using SKYPE4COMLib;
namespace ExcelDNASkype
{
public class ExcelDNASkype : IExcelAddIn
{
const int START_COLUMN = 0;
const int LAST_COLUMN = 1;
const string MENU_NORMAL = "一般";
const string MENU_SPECIAL = "特殊";
const string SKYPE_USER = "";
/// <summary>
/// アドインメニュー:一般
/// </summary>
[ExcelCommand(MenuName = "AddIn", MenuText = "Normal")]
public static void DisplayNormalMenu()
{
Run(MENU_NORMAL);
}
/// <summary>
/// アドインメニュー:特殊
/// </summary>
[ExcelCommand(MenuName = "AddIn", MenuText = "Special")]
public static void DisplaySpecialMenu()
{
Run(MENU_SPECIAL);
}
/// <summary>
/// メイン処理
/// </summary>
/// <param name="menuName">メニュー名</param>
private static void Run(string menuName)
{
// テキストファイル出力
var contents = CreateContents();
// .NET4 から登場した、Path.Combineのオーバーロードを利用
var txtpath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
menuName + "_content.txt");
MessageBox.Show(txtpath);
if (ExportTextFile(contents, txtpath)) MessageBox.Show(contents.Count.ToString() + " 件、出力しました。");
// Excelファイル保存
if (SaveAsExcelFile(txtpath)) MessageBox.Show("Excelファイルを保存しました。");
// Skype通知
if (SendSkypeMessage(menuName)) MessageBox.Show("Skype通知をしました。");
}
/// <summary>
/// 出力するテキストファイルデータの作成
/// </summary>
/// <returns>テキストファイルデータ</returns>
private static List<string> CreateContents()
{
var contents = new List<string>();
// 最初
for (int row = 1; row < 10000; row++)
{
var startNo = GetCellValue(row, START_COLUMN);
var lastNo = GetCellValue(row, LAST_COLUMN);
if (startNo == 0 && lastNo == 0) break;
var amount = lastNo - startNo + 1;
for (int i = 0; i < amount; i++)
{
contents.Add("x" + string.Format("{0:D4}", (startNo + i)) + "x");
}
}
// string.Formatを使う
for (int row = 1; row < 10000; row++)
{
var startNo = GetCellValue(row, START_COLUMN);
var lastNo = GetCellValue(row, LAST_COLUMN);
if (startNo == 0 && lastNo == 0) break;
var amount = lastNo - startNo + 1;
for (int i = 0; i < amount; i++)
{
contents.Add(string.Format("{0}{1:D4}{0}", "w", (startNo + i)));
}
}
// 内側のforループをLINQに変更
for (int row = 1; row < 10000; row++)
{
var startNo = GetCellValue(row, START_COLUMN);
var lastNo = GetCellValue(row, LAST_COLUMN);
if (startNo == 0 && lastNo == 0) break;
contents.AddRange(Enumerable.Range(0, lastNo - startNo + 1).Aggregate(new List<string>(), (list, i) =>
{
list.Add(string.Format("{0}{1:D4}{0}", "y", (startNo + i)));
return list;
}));
}
// 外側・内側ともforループを削除
var items = Enumerable.Range(1, 10000)
.Select((i) => new { startNo = GetCellValue(i, START_COLUMN), lastNo = GetCellValue(i, LAST_COLUMN) })
.TakeWhile(j => j.startNo != 0 || j.lastNo != 0);
foreach (var item in items)
{
var amount = item.lastNo - item.startNo + 1;
contents.AddRange(Enumerable.Range(0, amount).Aggregate(new List<string>(), (list, k) =>
{
list.Add(string.Format("{0}{1:D4}{0}", "z", (item.startNo + k)));
return list;
}));
}
return contents;
}
/// <summary>
/// セルの値を取得する
/// </summary>
/// <param name="row">セルの行(0始まり)</param>
/// <param name="column">セルの列(0始まり)</param>
/// <returns>セルの値、取得できない場合は、セルの値は0を返す</returns>
private static int GetCellValue(int row, int column)
{
var cell = new ExcelReference(row, column);
var value = 0;
if (int.TryParse(cell.GetValue().ToString(), out value)) return value;
else return 0;
}
/// <summary>
/// テキストファイルの出力
/// </summary>
/// <param name="contents">テキストファイルの内容</param>
/// <param name="fullpath">出力先のパス</param>
/// <returns></returns>
private static bool ExportTextFile(List<string> contents, string fullpath)
{
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("SHIFT_JIS");
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fullpath, true, encode))
{
foreach (var content in contents)
{
sw.WriteLine(content);
}
}
return true;
}
/// <summary>
/// Excelファイルとして保存
/// </summary>
/// <param name="txtpath">テキストファイルの出力先</param>
/// <returns></returns>
private static bool SaveAsExcelFile(string txtpath)
{
var regex = new System.Text.RegularExpressions.Regex("txt$");
var xlspath = regex.Replace(txtpath, "xls");
// Excel-DNAの機能を使用
XlCall.Excel(XlCall.xlcSaveAs, xlspath);
return true;
}
/// <summary>
/// Skypeメッセージの送信
/// </summary>
/// <returns></returns>
private static bool SendSkypeMessage(string menu)
{
// Skype4COMを使用
SKYPE4COMLib.Skype skype = new Skype();
skype.SendMessage(SKYPE_USER, menu);
return true;
}
// 以下、IExcelAddIn用で、今回は使用しない
public void AutoOpen() { }
public void AutoClose() { }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment