RunningCSharp

MS系開発者による、雑多な記事。記事は所属企業とは関係のない、個人の見解です。

PowerShell テキストファイルをソートして出力する

同フォルダのUTF-8のテキストファイル「output.txt」の内容を行単位で文字コード昇順でソートし、「output2.txt」に出力する例

Get-Content -Encoding UTF8 -Path "./output.txt" | Sort-Object | Set-Content  -Encoding UTF8 "./output2.txt" 

降順だと以下の通り。

Get-Content -Encoding UTF8 -Path "./output.txt" | Sort-Object -Descending | Set-Content  -Encoding UTF8 "./output2.txt" 

上記ソートのPowerShellコマンドをコマンドプロンプトから実施させる場合、以下のようにbatファイルを作成。(昇順の例)

test.bat

powershell -Command "Get-Content -Encoding UTF8 -Path './output.txt' | Sort-Object | Set-Content  -Encoding UTF8 './output2.txt'" 

「output.txt」に下記のような内容を格納し実行すると、

c
d
f
3
1
ぬ
5
@

「output2.txt」は下記のように出力される。

@
1
3
5
c
d
f
ぬ

VB(.net) Windows10 WinForms・DataGridViewのColumnHeaderのソートを示す三角だけ操作する

記のようなコードを実行した際、右側のカラムをクリックした際、ソートはされないがソートを示す三角形が「昇順→降順→ソートなし」の順に変化する。

コード

Imports System.ComponentModel

Public Class Form1
    'ソートの状態を保存する変数
    Dim sordOrder As SortOrder = SortOrder.None

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        '以下はDataGridViewのデータ表示用コード
        Dim table As DataTable = New DataTable()

        table.Columns.Add("col1")
        table.Columns.Add("col2")
        table.Rows.Add({1, 1})
        table.Rows.Add({2, 2})
        table.Rows.Add({4, 4})
        table.Rows.Add({3, 3})
        DataGridView1.DataSource = table

        '自動ソートを停止
        DataGridView1.Columns.Item(1).SortMode = DataGridViewColumnSortMode.Programmatic

    End Sub

    Private Sub DataGridView1_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
        '右側のカラムでのみ、「ソートなし」処理を実装
        If e.ColumnIndex = 1 Then
            Dim vc As DataGridViewColumn = DataGridView1.Columns.Item(e.ColumnIndex)
            'すでにソート中であれば、次のソート状態を保持
            sordOrder = GetNextOrder(sordOrder)

            '※データの独自ソートを行いたい場合は、ここでデータのソートを実施


            'カラムヘッダーの矢印を現在のソート状態に合わせる
            vc.HeaderCell.SortGlyphDirection = sordOrder

        End If

    End Sub

    'ソート順を受け取り、次のソート順を返す
    Private Function GetNextOrder(sortOrder As SortOrder) As SortOrder
        Dim rtn As SortOrder
        Select Case sortOrder
            Case SortOrder.Ascending
                rtn = SortOrder.Descending
            Case SortOrder.Descending
                rtn = SortOrder.None
            Case SortOrder.None
                rtn = SortOrder.Ascending
        End Select
        Return rtn
    End Function

End Class

f:id:ys-soniclab:20190119215201p:plain
クリック一回目

f:id:ys-soniclab:20190119215217p:plain
クリック二回目

f:id:ys-soniclab:20190119215232p:plain
クリック三回目

VB(.net) Windows10 WinForms・DataGridViewのカラムクリック時、「昇順→降順→ソートなし」の順となるようカスタム

デフォルトのDataGridViewはカラムをクリックすると、「昇順→降順」の順にソートされる。 この挙動を、「昇順→降順→ソートなし」となるようカスタムする。 下記例では、右側のカラムのみカスタムが実装される。

Imports System.ComponentModel

Public Class Form1
    'ソートの状態を保存する変数
    Dim sordOrder As SortOrder = SortOrder.None

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        '以下はDataGridViewのデータ表示用コード
        Dim table As DataTable = New DataTable()

        table.Columns.Add("col1")
        table.Columns.Add("col2")
        table.Rows.Add({1, 1})
        table.Rows.Add({2, 2})
        table.Rows.Add({4, 4})
        table.Rows.Add({3, 3})
        DataGridView1.DataSource = table

    End Sub

    Private Sub DataGridView1_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
        '右側のカラムでのみ、「ソートなし」処理を実装
        If e.ColumnIndex = 1 Then
            Dim vc As DataGridViewColumn = DataGridView1.Columns.Item(e.ColumnIndex)
            'すでにソート中であれば、次のソート状態を保持
            sordOrder = GetNextOrder(sordOrder)

            If sordOrder = SortOrder.None Then
                'ソート状態をリセット
                DataGridView1.DataSource.DefaultView.Sort = String.Empty
            Else
                'ソートを実行
                DataGridView1.Sort(vc, IIf(sordOrder = SortOrder.Ascending, ListSortDirection.Ascending, ListSortDirection.Descending))
            End If

        End If

    End Sub

    'ソート順を受け取り、次のソート順を返す
    Private Function GetNextOrder(sortOrder As SortOrder) As SortOrder
        Dim rtn As SortOrder
        Select Case sortOrder
            Case SortOrder.Ascending
                rtn = SortOrder.Descending
            Case SortOrder.Descending
                rtn = SortOrder.None
            Case SortOrder.None
                rtn = SortOrder.Ascending
        End Select
        Return rtn
    End Function

End Class

f:id:ys-soniclab:20190119214313p:plain
クリック一回目

f:id:ys-soniclab:20190119214333p:plain
クリック二回目

f:id:ys-soniclab:20190119214349p:plain
クリック三回目

VB(.net) Windows10 WinForms・DataGridViewのColumnHeaderのソートを示す三角が見えなくなる

下記のようなコードを実行した際、右側のカラムにて、ColumnHeaderのソート順を示す三角形が表示されなくなる。

コード

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
        DataGridView1.ColumnHeadersHeight = 20

        DataGridView1.Columns.Add("col1", "1")
        DataGridView1.Columns.Add("col2", "2222222222")
        DataGridView1.Rows.Add({1, 3})
        DataGridView1.Rows.Add({2, 4})

       DataGridView1.Columns().Item(1).Width = 110

    End Sub
End Class

実行結果

f:id:ys-soniclab:20190103185521p:plain
左側カラムでソート実施

f:id:ys-soniclab:20190103185545p:plain
右側カラムでソート実施

2枚目のスクリーンショットでは、右側のカラムでソートを実施しているが、ヘッダーに三角形が表示されない。 本問題は、文字がカラムいっぱいに広がることで、ソートを示す三角形が消えてしまうことで発生する。 カラムを広げる調整を行うことで、問題を回避できる。

コード

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
        DataGridView1.ColumnHeadersHeight = 20

        DataGridView1.Columns.Add("col1", "1")
        DataGridView1.Columns.Add("col2", "2222222222")
        DataGridView1.Rows.Add({1, 3})
        DataGridView1.Rows.Add({2, 4})

        '以下を追加
        DataGridView1.Columns().Item(1).Width = 110

    End Sub
End Class

実行結果

f:id:ys-soniclab:20190103190025p:plain
コード変更後

VB(.net) Windows10 WinFormsのDataGridViewのカスタム

本記事では、下記の方法をまとめて記載いたします。(挙動はWindows10にて確認済の内容となります)

①DataGridViewのヘッダー背景色変更

②DataGridViewのヘッダー文字色変更

③DataGridViewのヘッダー・項目それぞれのフォント変更

④DataGridViewのヘッダー・項目それぞれの文字の寄せ方変更

変更前のコードと画面は以下の通り。

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        DataGridView1.Columns.Add("col1", "漢字1")
        DataGridView1.Columns.Add("col2", "漢字2")
        DataGridView1.Rows.Add({"漢字3", 3})
        DataGridView1.Rows.Add({"漢字4", 4})

    End Sub
End Class

f:id:ys-soniclab:20181231204739p:plain
変更前

変更用コードと変更後画面は以下の通り。

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        DataGridView1.Columns.Add("col1", "漢字1")
        DataGridView1.Columns.Add("col2", "漢字2")
        DataGridView1.Rows.Add({"漢字3", 3})
        DataGridView1.Rows.Add({"漢字4", 4})

        '下記設定を行わないと、①と②の設定が反映されない
        DataGridView1.EnableHeadersVisualStyles = False

        '①DataGridViewのヘッダー背景色変更
        DataGridView1.Columns().Item(0).HeaderCell.Style.BackColor = Color.Red
        '②DataGridViewのヘッダー文字色変更
        DataGridView1.Columns().Item(1).HeaderCell.Style.ForeColor = Color.Green

        '③DataGridViewのヘッダー・項目それぞれのフォント変更
        'ヘッダーのフォント変更
        DataGridView1.Columns().Item(0).HeaderCell.Style.Font = New Font("MS 明朝", 8)
        DataGridView1.Columns().Item(1).HeaderCell.Style.Font = New Font("Meiryo UI", 15)
        '項目のフォント変更
        DataGridView1.Columns().Item(0).DefaultCellStyle.Font = New Font("MS ゴシック", 15)
        DataGridView1.Columns().Item(1).DefaultCellStyle.Font = New Font("MS P ゴシック", 8)

        '④DataGridViewのヘッダー・項目それぞれの文字の寄せ方変更
        'ヘッダーの寄せ方変更
        DataGridView1.Columns().Item(0).HeaderCell.Style.Alignment = DataGridViewContentAlignment.TopLeft
        DataGridView1.Columns().Item(1).HeaderCell.Style.Alignment = DataGridViewContentAlignment.BottomLeft

        '項目の寄せ方変更
        DataGridView1.Columns().Item(0).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
        DataGridView1.Columns().Item(1).DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomRight

        'ヘッダーの高さ変更
        '下記のプロパティ変更を行わないと、ColumnHeadersHeightが正しく反映されない
        DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
        DataGridView1.ColumnHeadersHeight = 100

    End Sub
End Class

f:id:ys-soniclab:20190103184425p:plain
変更後

VBでASP.net WebAPIを作る

ASP.net+VBでWebApiを作りたい。WebApiは呼ばれたらバッチを実行し、バッチ処理が完了した後にレスポンスを返してほしい。レスポンスは何でもよい。」とリクエストを受けたので、作ってみました。

WebApiの作り方は、下記の記事内容を引用させて頂きます。

blog.okazuki.jp

本記事は、ほとんど上記記事のコードをVBでやってみただけの記事になります。

プロジェクトを作る

空のASP.netプロジェクトを作成します。

f:id:ys-soniclab:20170204210936p:plain

NuGetで「Microsoft ASP.NET Web API 2 Web Host」を追加

f:id:ys-soniclab:20170204211017p:plain

本記事ではv5.2.3を利用しました。

Global.asaxの追加

プロジェクトを右クリックし、「追加」→「新しい項目を追加」を選択し、ダイアログで「Web」→「グローバル アプリケーション クラス」を選択。

f:id:ys-soniclab:20170204211129p:plain

作成された「Global.asax」を開き、下記のようにコードを追加します。

Imports System.Web.SessionState
'追加ここから
Imports System.Web.Http
'追加ここまで

Public Class Global_asax
    Inherits System.Web.HttpApplication

    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' アプリケーションの起動時に呼び出されます
        '追加ここから
        GlobalConfiguration.Configure(
            Sub(config)
                config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}",
                                           New With {.id = RouteParameter.Optional})
            End Sub)
        '追加ここまで
    End SubEnd Class

ControllerフォルダとControllerクラスの追加

プロジェクトを右クリックし、「追加」→「新しいフォルダー」でフォルダを追加、名前を「Controller」に変更します。 「Controller」フォルダを右クリックし、「追加」→「クラス」でクラスを追加する、名前は「ExecBatchController」とします。

f:id:ys-soniclab:20170204212746p:plain

メソッドの実装

ExecBatchControllerを下記のように書き換えます。 なお、C#ではGetのWebAPIを作成する場合「Get」とするが、VBでは「Get」が予約語であるため、「GetValues」とします。

Imports System.Web.Http

Public Class ExecBatchController
    Inherits ApiController

    Public Function GetValues() As String

        'バッチを実行(test.batはtimeout 20を実行する)
        Dim p As System.Diagnostics.Process =
            System.Diagnostics.Process.Start("C:\\test\\test.bat")
        p.WaitForExit()
        '適当な値を返す
        Return "end process"
    End Function

End Class

実行

実行すると、ブラウザにはエラーが表示されるが、WebAPIは起動しています。

f:id:ys-soniclab:20170204214346p:plain

ブラウザのアドレスバーに「http://localhost:(ポートNo)/api/ExecBatch」と入力すると、バッチが実行されます。

f:id:ys-soniclab:20170204214326p:plain

バッチ終了後、"end process"と文字列が返されます。

f:id:ys-soniclab:20170204214747p:plain

C#で書いたラムダ式を用いたコードをVBで書き直してみる

.netのVBを使い慣れない私が、今度はラムダ式を使ったテストコード(コンソールアプリケーション)をC#で書いた後、そのコードVBに書き直してみただけの記事です。

C#

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //文字列を返すだけのFunc
            Func<string> func = () => "returnvalue";
            //数値を3倍にして文字列で返すFunc
            Func<int, string> func2 = (i) =>
            {
                i = i * 3;
                return i.ToString();
            };
            //引数をコンソールに表示するだけのAction
            Action<string,string> action = (str1,str2) => 
            {
                Console.WriteLine(str1);
                Console.WriteLine(str2);
            };
            //Actionを実行
            action(func(), func2(2));

            //下記コードはコンソール画面を表示しておくために追加
            Console.ReadLine();
        }
    }
}

上記処理をVB(Visual Studio 2015)で書き直してみます。

Module Module1
    Sub Main()
        '文字列を返すだけのFunc
        Dim func As Func(Of String) = Function() "returnstring"
        '数値を3倍にして文字列で返すFunc
        Dim func2 As Func(Of String, Integer) =
            Function(i)
                i = i * 3
                Return i.ToString()
            End Function
        '引数をコンソールに表示するだけのAction
        Dim action As Action(Of String, String) =
        Sub(str1, str2)
            Console.WriteLine(str1)
            Console.WriteLine(str2)
        End Sub
        'Actionを実行
        action(func(), func2(2))

        '下記コードはコンソール画面を表示しておくために追加
        Console.ReadLine()
    End Sub
End Module

処理結果はどちらも

returnstring

6

となります。

LinqGUIのイベントにと使い道は非常に多いので、VBでのラムダ式の書き方は押さえておくと便利そうと感じました。 とりあえず書き溜めて、そのうちQiitaとかで纏めようかと思います。