前回の記事のコードを変更、昨日の追加をしました。
主な変更点と追加項目
1 非同期処理の導入
2 処理の中断機能の追加
3 パスの生成方法の変更
4 入力の検証
5 メソッドの追加
1非同期処理の導入
変更前のコードでは、メソッドが同期的に動作していたが、改良後のコードでは非同期処理を導入した。
Thread.SleepをTask.Delayに置き換え、非同期的な待機を行うように変更した。
変更前
private void button1_Click(object sender, EventArgs e)
{
// ...
Thread.Sleep(1000);
// ...
}
変更後
private async void button1_Click(object sender, EventArgs e)
{
// ...
await Task.Delay(1000, _cts.Token);
// ...
}
2処理の中断機能の追加
CancellationTokenSourceを使用して、処理を中断する機能を追加。
フォームデザイナで停止ボタンを追加。クリックイベントハンドラ(buttonStop_Click)を追加し、ここで処理の中断要求を行う。
private CancellationTokenSource _cts;
private void buttonStop_Click(object sender, EventArgs e)
{
if (_cts != null)
{
_cts.Cancel();
}
}
3パスの生成方法の変更
ファイルパスの生成にPath.Combineを使用するように変更した。
変更前
string filePass = $@"{textBox1.Text}\{textBox2.Text}.txt";
変更後
string filePass = Path.Combine(textBox1.Text, $"{textBox2.Text}.txt");
4入力の検証
テキストボックスが空でないか、ファイルが存在するかどうかの検証を追加。
if (string.IsNullOrWhiteSpace(textBox1.Text) || string.IsNullOrWhiteSpace(textBox2.Text))
{
MessageBox.Show("正しいパスを入力してください。");
return;
}
if (!File.Exists(filePass))
{
MessageBox.Show("指定されたファイルが存在しません。");
return;
}
5メソッドの追加
SendDataToExcelという新しいメソッドを追加した。
private void SendDataToExcel(string line, string key)
{
string cleanedData = line.Replace(key, "").Trim();
// ...
}
全コード
Form1
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TextFileInputOutput
{
public partial class Form1 : Form
{
private CancellationTokenSource _cts;
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
_cts = new CancellationTokenSource();
try
{
Microsoft.VisualBasic.Interaction.AppActivate("Excel");
if (string.IsNullOrWhiteSpace(textBox1.Text) || string.IsNullOrWhiteSpace(textBox2.Text))
{
MessageBox.Show("正しいパスを入力してください。");
return;
}
string filePass = Path.Combine(textBox1.Text, $"{textBox2.Text}.txt");
if (!File.Exists(filePass))
{
MessageBox.Show("指定されたファイルが存在しません。");
return;
}
var lines = File.ReadAllLines(filePass);
await Task.Delay(1000, _cts.Token); // CancellationTokenを追加
foreach (var line in lines)
{
if (_cts.Token.IsCancellationRequested)
{
// 中断要求があった場合、処理を終了
return;
}
if (line.Contains("X="))
{
SendDataToExcel(line, "X=");
}
else if (line.Contains("Y="))
{
SendDataToExcel(line, "Y=");
}
await Task.Delay(100, _cts.Token); // CancellationTokenを追加
}
}
catch (OperationCanceledException)
{
// 処理が中断されたときの処理(必要に応じて)
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SendDataToExcel(string line, string key)
{
string cleanedData = line.Replace(key, "").Trim();
if (key == "X=")
{
SendKeys.Send(cleanedData);
SendKeys.Send("{TAB}");
}
else if (key == "Y=")
{
SendKeys.Send(cleanedData);
SendKeys.Send("{ENTER}");
}
}
private void button2_Click(object sender, EventArgs e)
{
DialogResult dr = folderBrowserDialog1.ShowDialog();
if (dr == System.Windows.Forms.DialogResult.OK)
{
textBox1.Text = folderBrowserDialog1.SelectedPath;
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
if (_cts != null)
{
_cts.Cancel();
}
}
}
}
最後に
SendKeys.Sendはアクティブなウィンドウにキーイベントを送信します。ユーザーが操作中に別のウィンドウをアクティブにした場合など、誤ったウィンドウやアプリケーションにキー入力が送られるリスクがあので注意しましょう!