2013年9月1日日曜日

[VBA]ログを出力するクラスモジュール

[はじめに]
・最近、Excelマクロを使う機会が増えたので、
 備忘録としてサンプルを掲載します。
 クラスモジュールで定義することを前提としています。

[ソース]
''' <summary>
''' クラスモジュール名:LogForExcel
''' ログ出力を制御するクラス
''' </summary>
''' <remarks></remarks>
Option Explicit

'ログファイルのプレフィックス
Private Const LOG_FILE_PREFIX As String = "LOG_"
'ログファイルの拡張子
Private Const LOG_FILE_EXTENSION As String = ".log"
'ログファイルのバッファサイズ
Private Const LOG_BUF_SIZE As Integer = 1024

'ログ出力ディレクトリ
Public LogDirectory As String

'FileSystemObject
Private objFs As Object

'TextStreamObjectのIOモード
Private Enum IOMode
    ForReading = 0  '読み取り専用モード(既定値)
    ForWriting = 1  '上書きモード
    ForAppending = 8    '追記モード
End Enum

'ログ出力対象
Private colTraget As New Collection

''' <summary>
''' Initializeイベント(コンストラクタ)
''' </summary>
''' <remarks></remarks>
Private Sub Class_Initialize()
    Set objFs = CreateObject("Scripting.FileSystemObject")
    
    Call ClearLog
End Sub

''' <summary>
''' Terminateイベント(デストラクタ)
''' </summary>
''' <remarks></remarks>
Private Sub Class_Terminate()
    
    Call Flush
    
    Set objFs = Nothing

End Sub

''' <summary>
''' ログを出力する。[Information]
''' </summary>
''' <param name="msg">出力メッセージ</param>
''' <param name="useBuffer">バッファの利用有無</param>
''' <remarks></remarks>
Public Sub OutputInfo( _
    ByVal msg As String, _
    Optional ByVal useBuffer As Boolean = False)
    
    Call OutputLog("Informaton", msg, useBuffer)
    
End Sub

''' <summary>
''' ログを出力する。[Warning]
''' </summary>
''' <param name="msg">出力メッセージ</param>
''' <param name="useBuffer">バッファの利用有無</param>
''' <remarks></remarks>
Public Sub OutputWarn( _
    ByVal msg As String, _
    Optional ByVal useBuffer As Boolean = False)
    
    Call OutputLog("Warning", msg, useBuffer)
    
End Sub

''' <summary>
''' ログを出力する。[Error]
''' </summary>
''' <param name="msg">出力メッセージ</param>
''' <param name="objErr">エラーオブジェクト</param>
''' <param name="useBuffer">バッファの利用有無</param>
''' <remarks></remarks>
Public Sub OutputError( _
    ByVal msg As String, _
    Optional ByVal objErr As ErrObject = Nothing, _
    Optional ByVal useBuffer As Boolean = False)
    
    Dim strMsg As String
    
    strMsg = msg
    
    If Not (objErr Is NothingThen
        strMsg = strMsg & ":" & _
            "Err.Number:[" & objErr.Number & "]," & _
            "Err.Description:[" & objErr.Description & "]:"
    End If
    
    Call OutputLog("Error", strMsg, useBuffer)

End Sub

''' <summary>
''' ログを出力する。
''' </summary>
''' <param name="logType">ログ種別</param>
''' <param name="msg">出力メッセージ</param>
''' <param name="useBuffer">バッファの利用有無</param>
''' <remarks></remarks>
Private Sub OutputLog( _
    ByVal logType As String, _
    ByVal msg As String, _
    ByVal useBuffer As Boolean)

    colTraget.Add _
        Format(Now, "yyyy/mm/dd hh:mm:ss") & ":" & _
        logType & ":" & msg

    If useBuffer = True Then
        If colTraget.Count > LOG_BUF_SIZE Then
            'バッファがサイズを超えた場合は、ファイルに出力
            Me.Flush
        End If
    Else
        'バッファ無効の場合は、ファイルに出力
        Me.Flush
    End If

End Sub

''' <summary>
''' バッファーのデータをログに出力する。
''' </summary>
''' <remarks></remarks>
Public Sub Flush()
    
    Dim objTs As Object 'TextStreamObject
    Dim i As Long
    
    On Error GoTo LBL_ERR:
    
    Set objTs = objFs.OpenTextFile( _
        fileName:=objFs.BuildPath( _
            GetLogDirectory(), _
            LOG_FILE_PREFIX & _
            Format(Now, "yyyymmdd") & _
            LOG_FILE_EXTENSION), _
        IOMode:=IOMode.ForAppending, _
        Create:=True)


    For i = 1 To colTraget.Count
        objTs.WriteLine colTraget(i)
    Next
    
    objTs.Close
    Set objTs = Nothing
    Call ClearLog

   Exit Sub
LBL_ERR:
   
    If Not (objTs Is NothingThen
        objTs.Close
        Set objTs = Nothing
    End If
    
    Call ClearLog
    
    Err.Raise _
        Number:=Err.Number, _
        Description:="ログの出力に失敗しました。" & _
        Err.Description

End Sub

''' <summary>
''' ログ出力ディレクトリを取得する。
''' </summary>
''' <returns>ログ出力ディレクトリ(デフォルト:ThisWorkbook.path)</returns>
''' <remarks></remarks>
Private Function GetLogDirectory() As String
    If Me.LogDirectory = "" Then
        GetLogDirectory = ThisWorkbook.Path
        Exit Function
    End If
    
    GetLogDirectory = Me.LogDirectory

End Function

''' <summary>
''' バッファーをクリアする。
''' </summary>
''' <remarks></remarks>
Public Sub ClearLog()
    Dim i As Long
    
    For i = colTraget.Count To 1 Step -1
        colTraget.Remove i
    Next

End Sub
[VBA]ログを出力するクラスモジュール


[ソース]
Private Sub CommandButton1_Click()

    Dim logger As New LogForExcel
    
    On Error GoTo LBL_ERR
    
    'ログ出力[Info]
    Call logger.OutputInfo("出力テスト(Info)"True)
    'ログ出力[Warn]
    Call logger.OutputWarn("出力テスト(Warn)"True)
    
    'ゼロ除算で意図的に例外を発生させる。
    Debug.Print 1 / 0
    
    Set logger = Nothing
    
    Exit Sub
LBL_ERR:
    
    'ログ出力[Error]
    Call logger.OutputError("出力テスト(Error)", Err, True)
    
    Set logger = Nothing

End Sub
[VBA]使用例

2013年8月18日日曜日

[VBA]ファイル保存ダイアログの表示

[はじめに]
・最近、Excelマクロを使う機会が増えたので、
 備忘録としてサンプルを掲載します。
 VBAの関数が使いにくいので、クラスモジュールにまとめてみました。
 .NETのSaveFileDialogクラスを真似して実装しているので、
 .NET開発者にとっては、お馴染みのインタフェースで使いやすいかと思います。

[ソース]
''' <summary>
''' クラスモジュール名:SaveFileDialog
''' ファイル保存ダイアログを制御するクラス
''' </summary>
''' <remarks></remarks>
Option Explicit

'FileSystemPbject
Private objFs As Object

'タイトル
Public Title As String
'初期ディレクトリ
Public InitialDirectory As String
'初期ファイル名
Public InitialFileName As String
'[ファイルの種類]の選択肢
Public Filter As String
'[ファイルの種類]の選択値
Public FilterIndex As Integer

'選択したファイル名
Private m_FileName As String

''' <summary>
''' Initializeイベント(コンストラクタ)
''' </summary>
''' <remarks></remarks>
Private Sub Class_Initialize()
    Set objFs = CreateObject("Scripting.FileSystemObject")
    
    Call Clear
End Sub

''' <summary>
''' Terminateイベント(デストラクタ)
''' </summary>
''' <remarks></remarks>
Private Sub Class_Terminate()
    Set objFs = Nothing
End Sub


''' <summary>
''' 初期化
''' </summary>
''' <remarks></remarks>
Public Sub Clear()
    
    Me.InitialDirectory = Application.ThisWorkbook.path
    Me.InitialFileName = ""
    Me.Filter = "すべてのファイル(*.*),*.*"
    Me.FilterIndex = 1
    Me.Title = ""
    m_FileName = "ファイル名を指定してください"

End Sub

''' <summary>
''' フィルターを設定
''' </summary>
''' <param name="filterArray">フィルター文字列</param>
''' <remarks></remarks>
Public Sub SetFilterList(ParamArray filterArray() As Variant)
    Filter = Join(filterArray, ",")
End Sub

''' <summary>
''' 選択したファイル名を取得する。
''' </summary>
''' <remarks></remarks>
Public Function GetSelectedFileName() As String
    GetSelectedFileName = m_FileName
End Function

''' <summary>
''' パスとファイル名を結合する。
''' </summary>
''' <param name="path">パス</param>
''' <param name="fileName">ファイル名</param>
''' <returns>結合後のフルパス</returns>
''' <remarks></remarks>
Private Function BuildPath( _
    ByVal path As String, _
    ByVal fileName As StringAs String
    
    BuildPath = objFs.BuildPath(path, fileName)

End Function

''' <summary>
''' ファイル保存ダイアログを開く
''' </summary>
''' <returns>vbOK:ファイル選択、vbCancel:キャンセル</returns>
''' <remarks></remarks>
Public Function ShowDialog() As VbMsgBoxResult

    Dim resDlg As Variant
    Dim initDir As String
    
    '初期ディレクトリの存在チェック
    ' 存在しない場合は、Excelブックの配置ディレクトリに置き換える。
    If objFs.FolderExists(Me.InitialDirectory) = False Then
        Me.InitialDirectory = ThisWorkbook.path
    End If
    
    'ファイル選択ダイアログを開く
    resDlg = _
         Application.GetSaveAsFilename( _
              InitialFileName:= _
                BuildPath( _
                    Me.InitialDirectory, _
                    Me.InitialFileName), _
              FileFilter:=Me.Filter, _
              FilterIndex:=Me.FilterIndex, _
              Title:=Me.Title _
             )

    If resDlg = False Then
        'キャンセルした場合
        m_FileName = ""
        
        ShowDialog = vbCancel
        Exit Function
    End If
    
    'ファイル選択した場合
    m_FileName = resDlg
    
    ShowDialog = vbOK
    Exit Function
    
End Function

VBA]ファイル保存ダイアログ


[ソース]
Private Sub CommandButton1_Click()

    Dim sfd As New SaveFileDialog
    
    With sfd
        .InitialDirectory = "C:\Hoge"
        .InitialFileName = "abc.csv"
        .Title = "タイトル"
        .FilterIndex = 1
        .SetFilterList "CSV(*.csv),*.csv""すべてのファイル(*.*),*.*"
        
    End With
    
    'ファイル保存ダイアログを開く。
    If sfd.ShowDialog() = vbOK Then
        MsgBox sfd.GetSelectedFileName()
    Else
        MsgBox "キャンセルしました"
    End If
    
    '終了処理
    Set sfd = Nothing

End Sub
VBA]使用例

[VBA]ファイル選択ダイアログの表示

[はじめに]
・最近、Excelマクロを使う機会が増えたので、
 備忘録としてサンプルを掲載します。
 VBAの関数が使いにくいので、クラスモジュールにまとめてみました。
 .NETのOpenFileDialogクラスを真似して実装しているので、
 .NET開発者にとっては、お馴染みのインタフェースで使いやすいかと思います。

[ソース]
''' <summary>
''' クラスモジュール名:OpenFileDialog
''' ファイル選択ダイアログを制御するクラス
''' </summary>
''' <remarks></remarks>
Option Explicit

'FileSystemPbject
Private objFs As Object
'WScript.Shell
Private objWs As Object

'タイトル
Public Title As String
'初期ディレクトリ
Public InitialDirectory As String
'[ファイルの種類]の選択肢
Public Filter As String
'[ファイルの種類]の選択値
Public FilterIndex As Integer
'複数選択の可否
Public MultiSelect As Boolean

'選択したファイル名
Private m_FileNames() As String

''' <summary>
''' Initializeイベント(コンストラクタ)
''' </summary>
''' <remarks></remarks>
Private Sub Class_Initialize()
    Set objFs = CreateObject("Scripting.FileSystemObject")
    Set objWs = CreateObject("WScript.Shell")
    
    Call Clear
End Sub

''' <summary>
''' Terminateイベント(デストラクタ)
''' </summary>
''' <remarks></remarks>
Private Sub Class_Terminate()
    Set objFs = Nothing
    Set objWs = Nothing
End Sub

''' <summary>
''' 初期化
''' </summary>
''' <remarks></remarks>
Public Sub Clear()
    
    Me.InitialDirectory = Application.ThisWorkbook.path
    Me.Filter = "すべてのファイル(*.*),*.*"
    Me.FilterIndex = 1
    Me.Title = "ファイルを選択してください"
    Me.MultiSelect = True

    ReDim m_FileNames(0)
End Sub

''' <summary>
''' フィルターを設定
''' </summary>
''' <param name="filterArray">フィルター文字列</param>
''' <remarks></remarks>
Public Sub SetFilterList(ParamArray filterArray() As Variant)
    Filter = Join(filterArray, ",")
End Sub

''' <summary>
''' 選択したファイル名を取得する。
''' </summary>
''' <remarks></remarks>
Public Function GetSelectedFileNames() As String()
    GetSelectedFileNames = m_FileNames
End Function

''' <summary>
''' ファイル選択ダイアログを開く
''' </summary>
''' <returns>vbOK:ファイル選択、vbCancel:キャンセル</returns>
''' <remarks></remarks>
Public Function ShowDialog() As VbMsgBoxResult

    Dim resDlg As Variant

    'カレントディレクトリを設定
    objWs.CurrentDirectory = Me.InitialDirectory
     
    'ファイル選択ダイアログを開く
    resDlg = _
         Application.GetOpenFilename( _
              FileFilter:=Me.Filter, _
              FilterIndex:=Me.FilterIndex, _
              Title:=Me.Title, _
              MultiSelect:=Me.MultiSelect _
             )

    If IsArray(resDlg) = False Then
        If resDlg = False Then
            'キャンセルした場合
            ReDim m_FileNames(0)
            
            ShowDialog = vbCancel
            Exit Function
        End If
    End If
    
    ReDim m_FileNames(0)
    
    'ファイル選択した場合
    If IsArray(resDlg) = True Then
        '複数選択の場合
        Dim cnt_i As Integer
        
        For cnt_i = 1 To UBound(resDlg)
            ReDim Preserve m_FileNames(cnt_i - 1)
            m_FileNames(cnt_i - 1) = resDlg(cnt_i)
        Next
        
        ShowDialog = vbOK
        Exit Function
    Else
        '単一選択の場合
        ReDim m_FileNames(0)
        m_FileNames(0) = resDlg
    
        ShowDialog = vbOK
        Exit Function
    End If
    
End Function
[VBA]ファイル選択ダイアログ


[ソース]
Private Sub CommandButton1_Click()
    
    Dim ofd As New OpenFileDialog
    
    With ofd
        .Title = "ファイル選択ダイアログ(単一選択)"
        .FilterIndex = 1
        .MultiSelect = False
        .SetFilterList "CSV(*.csv),*.csv""すべてのファイル(*.*),*.*"
        
    End With
    
    'ファイル選択ダイアログを開く。
    If ofd.ShowDialog() = vbOK Then
        
        Dim cntI As Integer
        Dim fList() As String
        
        fList = ofd.GetSelectedFileNames()
        
        For cntI = 0 To UBound(fList)
            MsgBox fList(cntI)
        Next
    Else
        MsgBox "キャンセルしました"
    End If

    '終了処理
    Set ofd = Nothing

End Sub
[VBA]使用例

[VBA]指定したブック内のシート検索

[はじめに]
・最近、Excelマクロを使う機会が増えたので、備忘録としてサンプルを掲載します。
 指定したブック内のシートを検索する処理です。

[ソース]
Option Explicit

''' <summary>
''' 指定したブック検索する。
''' </summary>
''' <param name="bookName">ブック名</param>
''' <returns>対象のWorkBook。(存在しない場合はNothing)</returns>
''' <remarks></remarks>
Public Function FindBook( _
    ByVal bookName As StringAs Workbook

    Dim bk As Workbook
    
    For Each bk In Workbooks
        If bk.name = bookName Then
            Set FindBook = Workbooks(bk.name)
            Exit Function
        End If
    Next

End Function

''' <summary>
''' 指定したブック内のシートを検索する。
''' </summary>
''' <param name="sheetName">シート名</param>
''' <param name="bookName">ブック名(※省略時はThisWorkbook.Name)</param>
''' <returns>対象のWorkSheet。(存在しない場合はNothing)</returns>
''' <remarks></remarks>
Public Function FindSheet( _
    ByVal sheetName As String, _
    Optional ByVal bookName As String = ""As Worksheet

    Dim bk As Workbook
    Dim sht As Worksheet

    If bookName = "" Then
        'ブック名を省略した場合は、
        '自分自身のブックを対象とする。
        Set bk = ThisWorkbook
    Else
        Set bk = FindBook(bookName)
        
        If bk Is Nothing Then
            '指定したブック名が存在しない場合は、Nothingを返す。
            Set FindSheet = Nothing
            Exit Function
        End If
        
    End If
    
    For Each sht In bk.Sheets
        If sht.name = sheetName Then
            Set FindSheet = bk.Worksheets(sht.name)
            Exit Function
        End If
    Next

    'シートが存在しない場合、Nothingを返す。
    Set FindSheet = Nothing

End Function
[VBA]指定したブック内のシートを検索

2013年8月14日水曜日

[Book's Review (Develop)]〔速攻入門〕 C#プログラミング すぐに現場で使える知識

(1)レビュー
 JavaやC++の経験者向けのC#の入門書です。
 経験者向けの為、プログラミングの基礎知識の説明は割愛しています。
 その分、類似機能について他言語(Java、C++)との比較を交えたり等、
 より深い技術の解説が充実しています。
 本書の執筆時点では、
 .NET Framework4(C#4.0、VisualStudio2010)が最新版ですが、
 プレビュー版ですが、.NET Framework4.5(C#5.0)も紹介しています。

(2)リンク
〔速攻入門〕 C#プログラミング すぐに現場で使える知識

〔速攻入門〕 C#プログラミング すぐに現場で使える知識

  • 作者: 中 博俊
  • 出版社/メーカー: 技術評論社
  • 発売日: 2012/03/09
  • メディア: 単行本(ソフトカバー)

2012年4月3日火曜日

[Book's Review (Develop)]LINQテクノロジ入門

(1)レビュー
.NET Framework3.5、Visual Studio 2008から導入された
LINQ(Language Integrated Query)についての入門書です。
LINQの細かい文法よりも、
なぜこの技術が導入されたかの背景についてを重点に、
わかりやすく解説しています。

(2)リンク
LINQテクノロジ入門~Microsoft Visual Studio 2008による新たなクエリ構築技法~ (マイクロソフトコンサルティングサービステクニカルリファレンスシリーズ)

LINQテクノロジ入門~Microsoft Visual Studio 2008による新たなクエリ構築技法~ (マイクロソフトコンサルティングサービステクニカルリファレンスシリーズ)

  • 作者: 赤間信幸
  • 出版社/メーカー: 日経BPソフトプレス
  • 発売日: 2008/07/28
  • メディア: 単行本(ソフトカバー)

[Book's Review (Develop)]プログラミングC# 第6版

(1)レビュー
 .NET Framework4やC#の書籍で、
 入門編レベルよりもさらに踏み込んだ技術を習得したい方にお勧め!
 レベルの高い書籍だと、文章がわかりにくかったり、
 無駄にページ数が多かったり、『~編』のようにシリーズ化しているものが多いですが、
 この書籍はわかりやすくまとめてあります。
 また.NET Framework4の新機能(並行性、動的言語サポート、共変性と反変性)についての
 解説も充実しています。

(2)リンク
プログラミングC# 第6版

プログラミングC# 第6版

  • 作者: Ian Griffiths
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2011/11/29
  • メディア: 大型本

2012年2月23日木曜日

[Toy's Review]マスター将棋

(1)レビュー
友人が将棋を覚える為に
『マスター将棋』というのを購入しました。

初心者でもルールがわかるように、
コマに『動かし方』の絵が描いてあります。

説明書もマンガになっていて、
初心者が読んでも理解しやすいようになっています。

ただ難点をいうと、
ルールを知っている人からすると、
全てのコマが同じ大きさなので、
ぱっと見どれが大駒なのかわかりにくいことかな(笑)

歩兵も飛車も同じ大きさです。。。

(2)リンク
マスター将棋

マスター将棋

  • 出版社/メーカー: ビバリー
  • メディア: おもちゃ&ホビー
類似商品として『マスターチェス』なんてのもあるようです。
マスターチェス

マスターチェス

  • 出版社/メーカー: ビバリー
  • メディア: おもちゃ&ホビー

2011年12月9日金曜日

[Book's Review (Develop)]ASP.NET逆引き大全600の極意―ASP.NET2.0/3.5/4対応

(1)レビュー
今までありそうでなかった逆引きシリーズですが、
ASP.NETバージョン4にして初めて発売されました。(従来のASPはありましたが。。。)

よく使う機能から、.NETならではの新機能(メンバーシップ等)まで、
何気にカテゴリーを追いかけるだけでも面白いかもしれません。

ASP.NETをこれから始める人、更に理解を深めたい人にとっては、貴重な1冊だと思います。

(2)リンク
ASP.NET逆引き大全600の極意―ASP.NET2.0/3.5/4対応

ASP.NET逆引き大全600の極意―ASP.NET2.0/3.5/4対応

  • 作者: 山田 祥寛
  • 出版社/メーカー: 秀和システム
  • 発売日: 2011/09
  • メディア: 単行本

2011年8月21日日曜日

[Book's Review (Develop)].NETのクラスライブラリ設計 開発チーム直伝の設計原則、コーディング標準、パターン

(1)レビュー
.NETでシステム開発する際のガイドラインです。
ガイドラインだけならインターネットで検索すればでてきそうですが、
本書は、著者だけでなくたくさんの開発者からのコメントも寄稿されて、
実際の開発者の生の声や失敗談もまとめられています。

これから始める人、改善したい人にとっては、貴重な1冊だと思います。

(2)リンク
.NETのクラスライブラリ設計 開発チーム直伝の設計原則、コーディング標準、パターン (Microsoft.net Development Series)

.NETのクラスライブラリ設計 開発チーム直伝の設計原則、コーディング標準、パターン (Microsoft.net Development Series)

  • 作者: Krzysztof Cwalina
  • 出版社/メーカー: 日経BPソフトプレス
  • 発売日: 2009/12/24
  • メディア: 大型本

2011年6月9日木曜日

[VBA]罫線描画&罫線消去

[はじめに]
・Excelマクロで罫線描画、罫線消去を実装することがよくあります。
 『マクロの記録』で簡単に作れますが、汎用性がないので関数化しました。
 機能は単純に、セル範囲に罫線(外枠、内側の境界線)を描画するだけです。
 とりあえず、備忘録として載せておきます。

[ソース]
Option Explicit

''' <summary>
''' 指定したセル範囲に罫線を描画する。(外枠、内側の境界線)
''' </summary>
''' <param name="targetRange">対象セル範囲</param>
''' <remarks></remarks>
Public Sub DrawLine(ByVal targetRange As Range)
    With targetRange
    
        '個々のセルの右上がり斜線
        .Borders(xlDiagonalUp).LineStyle = xlNone
        
        '個々のセルの右下がり斜線
        .Borders(xlDiagonalDown).LineStyle = xlNone
        
        'セル範囲の最上端
        With .Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .ColorIndex = xlAutomatic
            .TintAndShade = 0
            .Weight = xlThin
        End With
        
        'セル範囲の最下端
        With .Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .ColorIndex = xlAutomatic
            .TintAndShade = 0
            .Weight = xlThin
        End With
        
        'セル範囲の最左端
        With .Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .ColorIndex = xlAutomatic
            .TintAndShade = 0
            .Weight = xlThin
        End With
        
        'セル範囲の最右端
        With .Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .ColorIndex = xlAutomatic
            .TintAndShade = 0
            .Weight = xlThin
        End With
        
        If .Cells(1).Row < .Cells(.Count).Row Then
            'セル範囲の上下端以外の境界線
            '【注意(Excel2003以前のみ】
            ' セル範囲が複数行にわたる場合のみ処理します。
            ' 単数行の場合に処理するとエラーになることがあります。
            With .Borders(xlInsideHorizontal)
                .LineStyle = xlContinuous
                .ColorIndex = xlAutomatic
                .TintAndShade = 0
                .Weight = xlThin
            End With
        End If

        If .Cells(1).Column < .Cells(.Count).Column Then
            'セル範囲の左右端以外の境界線
            '【注意(Excel2003以前のみ】
            ' セル範囲が複数列にわたる場合のみ処理します。
            ' 単数列の場合に処理するとエラーになることがあります。
            With .Borders(xlInsideVertical)
                .LineStyle = xlContinuous
                .ColorIndex = xlAutomatic
                .TintAndShade = 0
                .Weight = xlThin
            End With
        End If

    End With

End Sub

''' <summary>
''' 指定したセル範囲の罫線を消去する。(外枠、内側の境界線)
''' </summary>
''' <param name="targetRange">対象セル範囲</param>
''' <remarks></remarks>
Public Sub EraseLine(ByVal targetRange As Range)
    
    With targetRange
        
        '個々のセルの右上がり斜線
        .Borders(xlDiagonalUp).LineStyle = xlNone
        
        '個々のセルの右下がり斜線
        .Borders(xlDiagonalDown).LineStyle = xlNone
        
        'セル範囲の最上端
        .Borders(xlEdgeTop).LineStyle = xlNone
        
        'セル範囲の最下端
        .Borders(xlEdgeBottom).LineStyle = xlNone
        
        'セル範囲の最左端
        .Borders(xlEdgeLeft).LineStyle = xlNone
        
        'セル範囲の最右端
        .Borders(xlEdgeRight).LineStyle = xlNone
        
        If .Cells(1).Row < .Cells(.Count).Row Then
            'セル範囲の上下端以外の境界線
            '【注意(Excel2003以前のみ)】
            ' セル範囲が複数行にわたる場合のみ処理します。
            ' 単数行の場合に処理するとエラーになります。
            .Borders(xlInsideHorizontal).LineStyle = xlNone
        End If
        
        If .Cells(1).Column < .Cells(.Count).Column Then
            'セル範囲の左右端以外の境界線
            '【注意(Excel2003以前のみ)】
            ' セル範囲が複数列にわたる場合のみ処理します。
            ' 単数列の場合に処理するとエラーになることがあります。
            .Borders(xlInsideVertical).LineStyle = xlNone
        End If
        
    End With

End Sub
[ExcelVBA]罫線の描画&消去


Private Sub CommandButton1_Click()
    '罫線描画
    Call DrawLine(Selection)
End Sub

Private Sub CommandButton2_Click()
    '罫線消去
    Call EraseLine(Selection)
End Sub
[ExcelVBA]呼び出し例

2011年5月26日木曜日

[Algo]DQ1の復活の呪文解析

[はじめに]
 ドラゴンクエストI復活の呪文を解析するツールを
 作ってみました。
 オブジェクト指向言語で開発していますが、
 なるべく構造化プログラミングを意識して実装している為、
 他言語への移植はさほど難しくないと思います。
開発ツールMicrosoft Visual Studio 2010
プログラム言語Microsoft Visual Basic 2010
.NETバージョン.NET Framework 2.0
形式Windows Forms アプリケーション
[機能]
 復活の呪文からゲーム進行状況のパラメータを解析する。
 ゲーム進行状況のパラメータから復活の呪文を生成する。
[制限事項]
 入力データは、下記を前提としています。
 ・プレイヤーの名前:全角のひらがな(一部除く)、数字
 ・復活の呪文:全角のひらがな(一部除く)
 ・復活の呪文:全角5文字、7文字、5文字、3文字
 ブログに掲載できる容量に制限がある為、入力チェックを省いています。
 入力データが前提以外の場合、アベンドすることがあります。
[実行の方法(VisualStudio2010を想定)]
 ①Windowsフォームアプリのプロジェクトを作成し、
  下記ソースをプロジェクトに追加する。(プロジェクトの名称は何でもいい。)
ソース機能
FrmDq1.vbメイン画面のロジック
FrmDq1.Designer.vbメイン画面のデザイン(自動生成)
Dq1ConstData.vbアイテム、武器、鎧などのデータ
DataConverter.vb文字列と文字コードの相互変換
Dq1PasswordAnalizer.vb『復活の呪文』の解析/生成
Dq1Password.vb『復活の呪文』を表すクラス(文字列と文字コードを管理)
PlayerName.vbプレイヤーの名前を表すクラス(文字列と文字コードを管理)
PlayerInformation.vbプレイヤーの情報(所持金、経験値、イベントフラグ等)
 ②『FrmDq1.vb』をスタートアップフォームに設定する。
 ③Form1.vbを削除する。(新規プロジェクト作成時のデフォルトの画面)
 ④ビルドする。
 (※開発ツールの利用詳細は割愛)
 また、VisualStudio2010で開発していますが、
 .NET2.0上で動作するので、2005/2008でも利用できると思います。
 (※2005/2008では動作未確認)
[実行画面]  DQ1 - 復活の呪文解析ツール
[プログラムソース]
''' <summary>
''' データ変換クラス(文字列⇔数値配列)
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class DataConverter

#Region "チェック処理"
    ''' <summary>
    ''' 変換可能かチェックする。(数値配列→文字列)
    ''' </summary>
    ''' <param name="targetData">データ</param>
    ''' <param name="convTable">変換テーブル</param>
    ''' <param name="errMessage">エラーメッセージ(OKの場合は空文字列)</param>
    ''' <returns>変換可否</returns>
    ''' <remarks></remarks>
    Public Shared Function CanConvertNumToString( _
        ByVal targetData() As Integer, _
        ByVal convTable() As String, _
        ByRef errMessage As StringAs Boolean

        'エラーメッセージ初期化
        errMessage = ""

        Try
            If targetData Is Nothing Then
                errMessage = "引数不正[targetData]"
                Return False
            End If

            If convTable Is Nothing Then
                errMessage = "引数不正[convTable]"
                Return False
            End If

            If targetData.Length > 4 Then
                errMessage = "データが長すぎます。[targetData]"
                Return False
            End If

            For Each data As Integer In targetData
                If data < 0 OrElse data > convTable.Length - 1 Then
                    errMessage = "データ不正。[targetData]"
                    Return False
                End If
            Next

        Catch ex As Exception
            errMessage = _
                "予期せぬエラー" & _
                vbCrLf & ex.ToString()
            Return False
        End Try

        Return True
    End Function

    ''' <summary>
    ''' 変換可能かチェックする。(文字列→数値配列)
    ''' </summary>
    ''' <param name="targetData">データ</param>
    ''' <param name="convTable">変換テーブル</param>
    ''' <param name="errMessage">エラーメッセージ(OKの場合は空文字列)</param>
    ''' <returns>変換可否</returns>
    ''' <remarks></remarks>
    Public Shared Function CanStrToNum( _
        ByVal targetData As String, _
        ByVal convTable() As String, _
        ByRef errMessage As StringAs Boolean

        'エラーメッセージ初期化
        errMessage = ""

        Try
            If targetData Is Nothing Then
                errMessage = "引数不正[targetData]"
                Return False
            End If

            If convTable Is Nothing Then
                errMessage = "引数不正[convTable]"
                Return False
            End If

            If targetData.Length > 20 Then
                errMessage = "データが長すぎます。[targetData]"
                Return False
            End If

            For Each data As Char In targetData
                If Array.IndexOf(convTable, data.ToString()) = -1 Then
                    errMessage = "指定できる文字は以下のみです。" & vbCrLf & String.Join("、", convTable)
                    Return False
                End If
            Next

        Catch ex As Exception
            errMessage = _
                "予期せぬエラー" & _
                vbCrLf & ex.ToString()
            Return False
        End Try

        Return True
    End Function

#End Region

#Region "変換処理"
    ''' <summary>
    ''' データを変換する。(数値配列→文字列)
    ''' </summary>
    ''' <param name="targetData">データ</param>
    ''' <param name="convTable">変換テーブル</param>
    ''' <returns>変換後データ(変換できない場合はNothing)</returns>
    ''' <remarks></remarks>
    Public Shared Function ConvertNumToString( _
        ByVal targetData() As Integer, _
        ByVal convTable() As StringAs String

        Dim sb As New System.Text.StringBuilder()

        For i As Integer = 0 To targetData.Length - 1
            sb.Append(convTable(targetData(i)))
        Next

        Return sb.ToString()

    End Function


    ''' <summary>
    ''' データを変換する。(文字列→数値配列)
    ''' </summary>
    ''' <param name="targetData">データ</param>
    ''' <param name="convTable">変換テーブル</param>
    ''' <returns>変換後データ(変換できない場合はNothing)</returns>
    ''' <remarks></remarks>
    Public Shared Function ConvertStrToNum( _
        ByVal targetData As String, _
        ByVal convTable() As StringAs Integer()

        Dim rtn As New List(Of Integer)()

        For i As Integer = 0 To targetData.Length - 1
            Dim idx As Integer = Array.IndexOf(convTable, targetData(i).ToString())

            If idx < 0 Then
                Return Nothing
            End If

            rtn.Add(idx)
        Next

        Return rtn.ToArray()

    End Function

#End Region

End Class
[VB.NET]DataConverter.vb


''' <summary>
''' 固定値データ
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class Dq1ConstData

#Region "定数定義"
    ''' <summary>
    ''' 道具一覧
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ReadOnly ITEM_LIST() As String = New String() { _
         "なし""たいまつ""せいすい""キメラのつばさ", _
         "りゅうのうろこ""ようせいのふえ""せんしのゆびわ""ロトのしるし", _
         "おうじょのあい""のろいのベルト""ぎんのたてごと""しのくびかざり", _
         "たいようのいし""あまぐものつえ""にじのしずく", _
         "(不明)" _
    }

    ''' <summary>
    ''' 武器一覧
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ReadOnly WEAPON_LIST() As String = New String() { _
        "なし""たけざお""こんぼう""どうのつるぎ", _
        "てつのおの""はがねのつるぎ""ほのおのつるぎ""ロトのつるぎ" _
    }

    ''' <summary>
    ''' 鎧一覧
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ReadOnly ARMOR_LIST() As String = New String() { _
        "なし""ぬののふく""かわのふく""くさりかたびら", _
        "てつのよろい""はがねのよろい""まほうのよろい""ロトのよろい" _
    }

    ''' <summary>
    ''' 盾一覧
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ReadOnly SHIELD_LIST() As String = New String() { _
        "なし""かわのたて""てつのたて""みかがみのたて" _
    }


    ''' <summary>
    ''' レベル(経験値)一覧
    ''' Lv 1 の必要経験値 = LEVEL_LIST(0)
    ''' Lv n の必要経験値 = LEVEL_LIST(n-1)
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ReadOnly LEVEL_LIST() As Integer = New Integer() { _
        0, 7, 23, 47, 110, 220, 450, 800, 1300, 2000, _
        2900, 4000, 5500, 7500, 10000, 13000, 17000, 21000, 25000, 29000, _
        33000, 37000, 41000, 45000, 49000, 53000, 57000, 61000, 65000, 65535 _
    }

#End Region

#Region "メソッド定義"
    ''' <summary>
    ''' 経験値からレベルを取得する。
    ''' </summary>
    ''' <param name="exp">経験値</param>
    ''' <returns>レベル</returns>
    ''' <remarks></remarks>
    Public Shared Function GetLevel(ByVal exp As IntegerAs Integer

        If exp < 0 Then
            Throw New ArgumentOutOfRangeException("経験値の範囲が不正。")
        End If

        For i As Integer = LEVEL_LIST.Length - 1 To 0 Step -1
            If exp >= LEVEL_LIST(i) Then
                Return i + 1
            End If
        Next

        Return 0

    End Function

    ''' <summary>
    ''' 指定したレベルに達する為の経験値を取得する。
    ''' </summary>
    ''' <param name="level">レベル</param>
    ''' <returns>経験値</returns>
    ''' <remarks></remarks>
    Public Shared Function GetExp(ByVal level As IntegerAs Integer

        If level < 1 OrElse level > LEVEL_LIST.Length + 1 Then
            Throw New ArgumentOutOfRangeException("レベルの範囲が不正。")
        End If

        Return LEVEL_LIST(level - 1)

    End Function

#End Region

End Class

[VB.NET]Dq1ConstData.vb


''' <summary>
''' 復活の呪文(DQ1)
''' </summary>
''' <remarks></remarks>
Public Class Dq1Password

#Region "変数定義"
    ''' <summary>
    ''' 復活の呪文(文字列)
    ''' </summary>
    ''' <remarks></remarks>
    Private _pass As String = Nothing

    ''' <summary>
    ''' 復活の呪文(数値配列)
    ''' </summary>
    ''' <remarks></remarks>
    Private _passCode() As Integer = Nothing

    ''' <summary>
    ''' 変換テーブル
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ReadOnly CONVERT_TABLE() As String = _
        New String() { _
            "あ""い""う""え""お", _
            "か""き""く""け""こ", _
            "さ""し""す""せ""そ", _
            "た""ち""つ""て""と", _
            "な""に""ぬ""ね""の", _
            "は""ひ""ふ""へ""ほ", _
            "ま""み""む""め""も", _
            "や""ゆ""よ", _
            "ら""り""る""れ""ろ", _
            "わ", _
            "が""ぎ""ぐ""げ""ご", _
            "ざ""じ""ず""ぜ""ぞ", _
            "だ""ぢ""づ""で""ど", _
            "ば""び""ぶ""べ""ぼ", _
            "?" _
        }

#End Region

#Region "コンストラクタ"
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="pass">
    ''' 復活の呪文(文字列)
    ''' (例:「ふるいけや」「かわずとびこむ」「みずのおと」「ばしゃ」)
    ''' </param>
    ''' <remarks></remarks>
    Public Sub New(ByVal ParamArray pass() As String)
        MyClass.New(String.Join("", pass))
    End Sub

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="pass">
    ''' 復活の呪文(文字列)
    ''' (例:「ふるいけやかわずとびこむみずのおとばしゃ」)
    ''' </param>
    ''' <remarks></remarks>
    Public Sub New(ByVal pass As String)
        '復活の呪文(文字列)
        Me._pass = pass

        '復活の呪文(数値配列)
        Me._passCode = DataConverter.ConvertStrToNum(Me._pass, CONVERT_TABLE)

    End Sub

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="passCode">復活の呪文(数値配列)</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal passCode() As Integer)
        '名前(数値配列)
        Me._passCode = passCode

        '名前(文字列)
        Me._pass = DataConverter.ConvertNumToString(Me._passCode, CONVERT_TABLE)

    End Sub

#End Region

#Region "メソッド定義"
    ''' <summary>
    ''' 復活の呪文(文字列)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function ToString() As String
        Return Me._pass
    End Function

#End Region

#Region "アクセッサ定義"
    ''' <summary>
    ''' 復活の呪文(数値配列)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property PassCode() As Integer()
        Get
            Return Me._passCode
        End Get
    End Property

#End Region

End Class

[VB.NET]Dq1Password.vb


''' <summary>
''' 復活の呪文(DQ1)の解析クラス
''' </summary>
''' <remarks></remarks>
Public Class Dq1PasswordAnalizer

#Region "チェックコード"

    ''' <summary>
    ''' チェックコード
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared ReadOnly CHECK_CODE() As Integer = New Integer() {
        &H88, &HC4, &H62, &H31, &H8, &H84, &H42, &H21, _
        &H98, &HCC, &HE6, &H73, &HA9, &HC4, &H62, &H31, _
        &H5A, &HAD, &HC6, &H63, &HA1, &HC0, &H60, &H30, _
        &H38, &H9C, &H4E, &HA7, &HC3, &HF1, &H68, &HB4, _
        &HD0, &H68, &HB4, &H5A, &H2D, &H6, &H83, &H51, _
        &H20, &H10, &H8, &H84, &H42, &HA1, &H40, &HA0, _
        &HF9, &HEC, &HF6, &H7B, &HAD, &HC6, &HE3, &H61, _
        &H81, &HD0, &H68, &HB4, &HDA, &H6D, &HA6, &HD3, _
        &HB2, &HD9, &HFC, &HFE, &HFF, &HEF, &H67, &H23, _
        &H34, &H1A, &HD, &H96, &H4B, &H35, &H8A, &H45, _
        &HAA, &HD5, &H7A, &H3D, &H8E, &H47, &HB3, &H49, _
        &HA1, &H40, &HA0, &H50, &HA8, &HD4, &HEA, &H75, _
        &HA0, &HD0, &H68, &HB4, &H5A, &HAD, &HC6, &H63, _
        &H7E, &HBF, &HCF, &HF7, &H6B, &HA5, &HC2, &H61 _
    }

#End Region

#Region "プレイヤー情報から復活の呪文を取得する。"
    ''' <summary>
    ''' プレイヤー情報から復活の呪文を取得する。
    ''' </summary>
    ''' <param name="pInfo">プレイヤー情報</param>
    ''' <returns>復活の呪文</returns>
    ''' <remarks></remarks>
    Public Function GetPasswordFromPlayerInfo(ByVal pInfo As PlayerInformation) As Dq1Password

        Dim data() As Integer = New Integer(19) {}
        Dim code() As Integer = New Integer(14) {}

        code(0) = _
                (pInfo.ItemList(1) << 4) Or _
                pInfo.ItemList(0)
        code(1) = _
                (pInfo.Flag1 << 7) Or _
                (pInfo.Name.NameCode(1) << 1) Or _
                (pInfo.Flag2)
        code(2) = (pInfo.Experience >> 8) And &HFF
        code(3) = _
                (pInfo.ItemList(5) << 4) Or _
                pInfo.ItemList(4)
        code(4) = _
                (pInfo.MagicKeyNum << 4) Or _
                pInfo.HerbNum
        code(5) = (pInfo.Gold >> 8) And &HFF
        code(6) = _
                (pInfo.Weapon << 5) Or _
                (pInfo.Armor << 2) Or _
                pInfo.Shild
        code(7) = _
                ((pInfo.CryptKey << 5) And &H80) Or _
                (pInfo.Flag3 << 6) Or _
                pInfo.Name.NameCode(3)
        code(8) = _
                (pInfo.ItemList(7) << 4) Or _
                pInfo.ItemList(6)
        code(9) = _
                (pInfo.Name.NameCode(0) << 2) Or _
                (pInfo.Flag4 << 1) Or _
                ((pInfo.CryptKey >> 1) And &H1)
        code(10) = pInfo.Gold And &HFF
        code(11) = _
                (pInfo.ItemList(3) << 4) Or _
                pInfo.ItemList(2)
        code(12) = _
                ((pInfo.CryptKey << 7) And &H80) Or _
                (pInfo.Flag5 << 6) Or _
                pInfo.Name.NameCode(2)
        code(13) = pInfo.Experience And &HFF
        code(14) = 0

        'チェックコードを計算する
        For i As Integer = 0 To 13
            For j As Integer = 0 To 7
                If (code(i) And (&H80 >> j)) <> 0 AndAlso CHECK_CODE(i * 8 + j) <> &H0 Then
                    code(14) = code(14) Xor CHECK_CODE(i * 8 + j)
                End If
            Next
        Next

        '8bit毎の code() を、 6bit毎の data() に変換
        Dim k As Integer = 0

        For i As Integer = 14 To 0 Step -3
            Dim w As Long = _
                (code(i - 2) << 16) Or _
                (code(i - 1) << 8) Or _
                (code(i))

            data(k) = w And &H3F : k += 1
            data(k) = (w >> 6) And &H3F : k += 1
            data(k) = (w >> 12) And &H3F : k += 1
            data(k) = (w >> 18) And &H3F : k += 1

        Next

        '4を加算し、data() を累計する
        Dim work As Integer = 0
        Dim passCode As New List(Of Integer)()

        For i As Integer = 0 To 19
            passCode.Add((data(i) + work + 4) And &H3F)
            work = passCode(i)
        Next

        '復活の呪文
        Dim pass As New Dq1Password(passCode.ToArray())

        Return pass

    End Function

#End Region

#Region "プレイヤー情報から復活の呪文を取得する。"

    ''' <summary>
    ''' プレイヤー情報から復活の呪文を取得する。
    ''' </summary>
    ''' <param name="pass">復活の呪文</param>
    ''' <returns>プレイヤー情報</returns>
    ''' <remarks></remarks>
    Public Function GetPlayerInfoFromPassword(ByVal pass As Dq1Password) As PlayerInformation
        Return Me.GetPlayerInfoFromPassword(pass.ToString())
    End Function


    ''' <summary>
    ''' プレイヤー情報から復活の呪文を取得する。
    ''' </summary>
    ''' <param name="pass">復活の呪文</param>
    ''' <returns>プレイヤー情報</returns>
    ''' <remarks></remarks>
    Public Function GetPlayerInfoFromPassword(ByVal pass As StringAs PlayerInformation

        Dim data(19) As Integer
        Dim code(14) As Integer

        '復活の呪文の文字コード
        Dim passCode() As Integer = DataConverter.ConvertStrToNum( _
                pass, _
                Dq1Password.CONVERT_TABLE _
            )

        '4 を引き、前後の文字の差分を取る
        For i As Integer = 19 To 1 Step -1
            data(i) = (passCode(i) - passCode(i - 1) - 4) And &H3F
        Next

        data(0) = (passCode(0) - 4) And &H3F

        '6bit毎のdata() を、 8bit毎のcode()に変換
        Dim j As Integer = 0

        For i As Integer = 19 To 0 Step -4
            Dim w As Long = _
                (data(i) << 18) Or _
                (data(i - 1) << 12) Or _
                (data(i - 2) << 6) Or _
                 data(i - 3)
            code(j) = (w >> 16) And &HFF : j += 1
            code(j) = (w >> 8) And &HFF : j += 1
            code(j) = w And &HFF : j += 1
        Next

        'チェックコードを計算する
        For i As Integer = 0 To 13
            For jj As Integer = 0 To 7
                If (code(i) And (&H80 >> jj)) <> 0 AndAlso CHECK_CODE(i * 8 + jj) <> &H0 Then
                    code(14) = code(14) Xor CHECK_CODE(i * 8 + jj)
                End If
            Next
        Next

        Dim pInfo As New PlayerInformation()

        pInfo.CheckCode = code(14)

        pInfo.Name = New PlayerName( _
                New Integer() { _
                    (code(9) >> 2) And &H3F, _
                    (code(1) >> 1) And &H3F, _
                    (code(12)) And &H3F, _
                    (code(7)) And &H3F _
                }
            )

        pInfo.Weapon = (code(6) >> 5) And &H7
        pInfo.Armor = (code(6) >> 2) And &H7
        pInfo.Shild = code(6) And &H3

        pInfo.ItemList(0) = code(0) And &HF
        pInfo.ItemList(1) = (code(0) >> 4) And &HF
        pInfo.ItemList(2) = code(11) And &HF
        pInfo.ItemList(3) = (code(11) >> 4) And &HF
        pInfo.ItemList(4) = code(3) And &HF
        pInfo.ItemList(5) = (code(3) >> 4) And &HF
        pInfo.ItemList(6) = code(8) And &HF
        pInfo.ItemList(7) = (code(8) >> 4) And &HF

        pInfo.MagicKeyNum = (code(4) >> 4) And &HF
        pInfo.HerbNum = code(4) And &HF

        pInfo.Experience = code(2) * 256 + code(13)
        pInfo.Gold = code(5) * 256 + code(10)

        pInfo.Flag1 = (code(1) >> 7) And &H1
        pInfo.Flag2 = code(1) And &H1
        pInfo.Flag3 = (code(7) >> 6) And &H1
        pInfo.Flag4 = (code(9) >> 1) And &H1
        pInfo.Flag5 = (code(12) >> 6) And &H1

        pInfo.CryptKey = _
                ((code(7) >> 5) And &H4) Or _
                ((code(9) << 1) And &H2) Or _
                ((code(12) >> 7) And &H1)

        pInfo.Level = Dq1ConstData.GetLevel(pInfo.Experience)

        '呪文が正しいかどうかをチェック
        If pInfo.CheckCode <> 0 OrElse _
            pInfo.MagicKeyNum > 6 OrElse _
            pInfo.HerbNum > 6 Then
            Return Nothing
        End If

        For i As Integer = 0 To 7
            If pInfo.ItemList(i) >= 15 Then
                Return Nothing
            End If
        Next

        Return pInfo

    End Function

#End Region

End Class
[VB.NET]Dq1PasswordAnalizer.vb


[プログラムソース]
''' <summary>
''' プレーヤー情報
''' </summary>
''' <remarks></remarks>
Public Class PlayerInformation

#Region "変数定義"
    ''' <summary>
    ''' レベル:出力用
    ''' </summary>
    ''' <remarks></remarks>
    Public Level As Integer = 0

    ''' <summary>
    ''' プレイヤーの名前
    ''' </summary>
    ''' <remarks></remarks>
    Public Name As PlayerName = Nothing

    ''' <summary>
    ''' 武器(0~7)
    ''' </summary>
    ''' <remarks></remarks>
    Public Weapon As Integer = 0

    ''' <summary>
    ''' 鎧(0~7)
    ''' </summary>
    ''' <remarks></remarks>
    Public Armor As Integer = 0

    ''' <summary>
    ''' 盾(0~3)
    ''' </summary>
    ''' <remarks></remarks>
    Public Shild As Integer = 0

    ''' <summary>
    ''' 道具(8個)
    ''' 各々の要素(0~14)
    ''' </summary>
    ''' <remarks></remarks>
    Public ItemList() As Integer = New Integer() {0, 0, 0, 0, 0, 0, 0, 0}

    ''' <summary>
    ''' 魔法の鍵の保持数(0~6)
    ''' </summary>
    ''' <remarks></remarks>
    Public MagicKeyNum As Integer = 0

    ''' <summary>
    ''' 薬草の保持数(0~6)
    ''' </summary>
    ''' <remarks></remarks>
    Public HerbNum As Integer = 0

    ''' <summary>
    ''' 経験値(0~65535)
    ''' </summary>
    ''' <remarks></remarks>
    Public Experience As Integer = 0

    ''' <summary>
    ''' ゴールド(0~65535)
    ''' </summary>
    ''' <remarks></remarks>
    Public Gold As Integer = 0

    ''' <summary>
    ''' フラグ1
    ''' (竜の鱗を装備したことがあるか?)
    ''' はい:1、いいえ:0
    ''' </summary>
    ''' <remarks></remarks>
    Public Flag1 As Integer = 0

    ''' <summary>
    ''' フラグ2
    ''' (戦士の指輪を装備しているか?)
    ''' はい:1、いいえ:0
    ''' </summary>
    ''' <remarks></remarks>
    Public Flag2 As Integer = 0

    ''' <summary>
    ''' フラグ3
    ''' (ドラゴンを倒したか?)
    ''' はい:1、いいえ:0
    ''' </summary>
    ''' <remarks></remarks>
    Public Flag3 As Integer = 0

    ''' <summary>
    ''' フラグ4
    ''' (ゴーレムを倒したか?)
    ''' はい:1、いいえ:0
    ''' </summary>
    ''' <remarks></remarks>
    Public Flag4 As Integer = 0

    ''' <summary>
    ''' フラグ5
    ''' (死の首飾りを入手したことがあるか?)
    ''' はい:1、いいえ:0
    ''' </summary>
    ''' <remarks></remarks>
    Public Flag5 As Integer = 0

    ''' <summary>
    ''' 暗号化のキー
    ''' </summary>
    ''' <remarks></remarks>
    Public CryptKey As Integer = 0

    ''' <summary>
    ''' チェックコード:出力用
    ''' </summary>
    ''' <remarks></remarks>
    Public CheckCode As Integer = 0

#End Region

End Class

[VB.NET]PlayerInformation.vb


''' <summary>
''' プレイヤーの名前
''' </summary>
''' <remarks></remarks>
Public Class PlayerName

#Region "変数定義"
    ''' <summary>
    ''' 名前(文字列)
    ''' </summary>
    ''' <remarks></remarks>
    Private _name As String = Nothing

    ''' <summary>
    ''' 名前(数値配列)
    ''' </summary>
    ''' <remarks></remarks>
    Private _nameCode() As Integer = Nothing

    ''' <summary>
    ''' 変換テーブル
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared CONVERT_TABLE() As String = _
        New String() { _
            "0""1""2""3""4", _
            "5""6""7""8""9", _
            "あ""い""う""え""お", _
            "か""き""く""け""こ", _
            "さ""し""す""せ""そ", _
            "た""ち""つ""て""と", _
            "な""に""ぬ""ね""の", _
            "は""ひ""ふ""へ""ほ", _
            "ま""み""む""め""も", _
            "や""ゆ""よ", _
            "ら""り""る""れ""ろ", _
            "わ""を""ん", _
            "っ""ゃ""ゅ""ょ", _
            "゛""゜""-"" " _
        }

#End Region

#Region "コンストラクタ"
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="name">名前(文字列)</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal name As String)
        '名前(文字列)
        Me._name = name.PadRight(4, " ")

        '名前(数値配列)
        Me._nameCode = DataConverter.ConvertStrToNum(Me._name, CONVERT_TABLE)

    End Sub

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="nameCode">名前(数値配列)</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal nameCode() As Integer)
        '名前(数値配列)
        Me._nameCode = nameCode

        '名前(文字列)
        Me._name = DataConverter.ConvertNumToString(Me._nameCode, CONVERT_TABLE)

    End Sub

#End Region

#Region "メソッド定義"
    ''' <summary>
    ''' 名前(文字列)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function ToString() As String
        Return Me._name
    End Function

#End Region


#Region "アクセッサ定義"
    ''' <summary>
    ''' 名前(数値配列)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property NameCode() As Integer()
        Get
            Return Me._nameCode
        End Get
    End Property

#End Region

End Class

[VB.NET]PlayerName.vb


''' <summary>
''' 「DQ1 - 復活の呪文解析ツール」
''' </summary>
''' <remarks></remarks>
Public Class FrmDq1

    ''' <summary>
    '''道具コンボボックスの配列
    ''' </summary>
    ''' <remarks></remarks>
    Private _cmbItemList() As ComboBox = Nothing

    ''' <summary>
    ''' 画面起動時
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub FrmDq1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
        '武器
        Me.cmbWeapon.DataSource = Dq1ConstData.WEAPON_LIST
        '鎧
        Me.cmbArmor.DataSource = Dq1ConstData.ARMOR_LIST
        '盾
        Me.cmbShield.DataSource = Dq1ConstData.SHIELD_LIST

        '道具
        Me.cmbItem1.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem2.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem3.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem4.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem5.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem6.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem7.DataSource = Dq1ConstData.ITEM_LIST.Clone()
        Me.cmbItem8.DataSource = Dq1ConstData.ITEM_LIST.Clone()

        '道具
        Me._cmbItemList = New ComboBox() {
            Me.cmbItem1, Me.cmbItem2, Me.cmbItem3, Me.cmbItem4, _
            Me.cmbItem5, Me.cmbItem6, Me.cmbItem7, Me.cmbItem8
        }

    End Sub


    ''' <summary>
    ''' 「解析」ボタン
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnGetParam_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles btnGetParam.Click

        'パスワードを変換(文字列→数値)
        Dim passAnlz As New Dq1PasswordAnalizer()

        Dim passInfo As New Dq1Password( _
            Me.txtPass1.Text.Trim(), _
            Me.txtPass2.Text.Trim(), _
            Me.txtPass3.Text.Trim(), _
            Me.txtPass4.Text.Trim())

        If passInfo Is Nothing Then
            MessageBox.Show("復活の呪文が違います。""エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        Dim plInfo As PlayerInformation = passAnlz.GetPlayerInfoFromPassword(passInfo)

        If plInfo Is Nothing Then
            MessageBox.Show("復活の呪文が違います。""エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        Me.txtLevel.Text = plInfo.Level.ToString()

        Me.txtPlayerName.Text = plInfo.Name.ToString()
        Me.numGold.Value = plInfo.Gold
        Me.numExp.Value = plInfo.Experience
        Me.numHerb.Value = plInfo.HerbNum
        Me.numKey.Value = plInfo.MagicKeyNum

        Me.cmbWeapon.SelectedIndex = plInfo.Weapon
        Me.cmbArmor.SelectedIndex = plInfo.Armor
        Me.cmbShield.SelectedIndex = plInfo.Shild

        For i As Integer = 0 To Me._cmbItemList.Length - 1
            Me._cmbItemList(i).SelectedIndex = plInfo.ItemList(i)
        Next

        Me.chkFlag1.Checked = plInfo.Flag1 = 1
        Me.chkFlag2.Checked = plInfo.Flag2 = 1
        Me.chkFlag3.Checked = plInfo.Flag3 = 1
        Me.chkFlag4.Checked = plInfo.Flag4 = 1
        Me.chkFlag5.Checked = plInfo.Flag5 = 1

        Me.numCrypt.Value = plInfo.CryptKey
        Me.txtResult.Text = plInfo.CheckCode.ToString()

        If plInfo.CheckCode <> 0 Then
            '基本的にはありえないですが。。。
            MessageBox.Show("復活の呪文が違います。(一部だけ)""エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

    End Sub

    ''' <summary>
    ''' 「生成」ボタン
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnGetPass_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles btnGetPass.Click

        Dim plInfo As New PlayerInformation()

        plInfo.Name = New PlayerName(Me.txtPlayerName.Text)

        If plInfo.Name.NameCode Is Nothing Then
            MessageBox.Show("名前が不正です。""エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        plInfo.Gold = Me.numGold.Value
        plInfo.Experience = Me.numExp.Value
        plInfo.HerbNum = Me.numHerb.Value
        plInfo.MagicKeyNum = Me.numKey.Value

        plInfo.Weapon = Me.cmbWeapon.SelectedIndex
        plInfo.Armor = Me.cmbArmor.SelectedIndex
        plInfo.Shild = Me.cmbShield.SelectedIndex

        For i As Integer = 0 To Me._cmbItemList.Length - 1
            plInfo.ItemList(i) = Me._cmbItemList(i).SelectedIndex
        Next

        plInfo.Flag1 = IIf(Me.chkFlag1.Checked, 1, 0)
        plInfo.Flag2 = IIf(Me.chkFlag2.Checked, 1, 0)
        plInfo.Flag3 = IIf(Me.chkFlag3.Checked, 1, 0)
        plInfo.Flag4 = IIf(Me.chkFlag4.Checked, 1, 0)
        plInfo.Flag5 = IIf(Me.chkFlag5.Checked, 1, 0)

        plInfo.CryptKey = Me.numCrypt.Value

        Dim passAnlz As New Dq1PasswordAnalizer()

        Dim dqPass As String = _
            passAnlz.GetPasswordFromPlayerInfo(plInfo).ToString().PadRight(20, " ")

        Me.txtPass1.Text = dqPass.PadRight(20, " ").Substring(0, 5)
        Me.txtPass2.Text = dqPass.PadRight(20, " ").Substring(5, 7)
        Me.txtPass3.Text = dqPass.PadRight(20, " ").Substring(12, 5)
        Me.txtPass4.Text = dqPass.PadRight(20, " ").Substring(17, 3)

    End Sub

    ''' <summary>
    ''' 「経験値」変更
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub numExp_ValueChanged(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles numExp.ValueChanged
        Me.txtLevel.Text = Dq1ConstData.GetLevel(Me.numExp.Value).ToString()
    End Sub

    ''' <summary>
    ''' テキストボックスのフォーカス取得時
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub txtCommon_Enter(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles _
        txtPass1.Enter, txtPass2.Enter, txtPass3.Enter, txtPass4.Enter, _
        txtLevel.Enter, txtPlayerName.Enter, txtResult.Enter

        CType(sender, TextBox).SelectAll()
    End Sub


End Class

[VB.NET]FrmDq1.vb


<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class FrmDq1
    Inherits System.Windows.Forms.Form

    'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Windows フォーム デザイナーで必要です。
    Private components As System.ComponentModel.IContainer

    'メモ: 以下のプロシージャは Windows フォーム デザイナーで必要です。
    'Windows フォーム デザイナーを使用して変更できます。  
    'コード エディターを使って変更しないでください。
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.lblPass = New System.Windows.Forms.Label()
        Me.txtPlayerName = New System.Windows.Forms.TextBox()
        Me.numHerb = New System.Windows.Forms.NumericUpDown()
        Me.numKey = New System.Windows.Forms.NumericUpDown()
        Me.cmbShield = New System.Windows.Forms.ComboBox()
        Me.cmbWeapon = New System.Windows.Forms.ComboBox()
        Me.cmbArmor = New System.Windows.Forms.ComboBox()
        Me.cmbItem1 = New System.Windows.Forms.ComboBox()
        Me.cmbItem2 = New System.Windows.Forms.ComboBox()
        Me.cmbItem3 = New System.Windows.Forms.ComboBox()
        Me.cmbItem6 = New System.Windows.Forms.ComboBox()
        Me.cmbItem5 = New System.Windows.Forms.ComboBox()
        Me.cmbItem4 = New System.Windows.Forms.ComboBox()
        Me.cmbItem8 = New System.Windows.Forms.ComboBox()
        Me.cmbItem7 = New System.Windows.Forms.ComboBox()
        Me.chkFlag1 = New System.Windows.Forms.CheckBox()
        Me.chkFlag5 = New System.Windows.Forms.CheckBox()
        Me.chkFlag4 = New System.Windows.Forms.CheckBox()
        Me.chkFlag3 = New System.Windows.Forms.CheckBox()
        Me.chkFlag2 = New System.Windows.Forms.CheckBox()
        Me.numCrypt = New System.Windows.Forms.NumericUpDown()
        Me.txtResult = New System.Windows.Forms.TextBox()
        Me.btnGetParam = New System.Windows.Forms.Button()
        Me.btnGetPass = New System.Windows.Forms.Button()
        Me.lblName = New System.Windows.Forms.Label()
        Me.lblGold = New System.Windows.Forms.Label()
        Me.lblExp = New System.Windows.Forms.Label()
        Me.lblHerb = New System.Windows.Forms.Label()
        Me.lblKey = New System.Windows.Forms.Label()
        Me.lblWeapon = New System.Windows.Forms.Label()
        Me.lblShield = New System.Windows.Forms.Label()
        Me.lblArmor = New System.Windows.Forms.Label()
        Me.grpItem = New System.Windows.Forms.GroupBox()
        Me.grpFlag = New System.Windows.Forms.GroupBox()
        Me.lblResult = New System.Windows.Forms.Label()
        Me.lblCrypt = New System.Windows.Forms.Label()
        Me.txtLevel = New System.Windows.Forms.TextBox()
        Me.lblLevel = New System.Windows.Forms.Label()
        Me.numGold = New System.Windows.Forms.NumericUpDown()
        Me.numExp = New System.Windows.Forms.NumericUpDown()
        Me.txtPass1 = New System.Windows.Forms.TextBox()
        Me.txtPass2 = New System.Windows.Forms.TextBox()
        Me.txtPass3 = New System.Windows.Forms.TextBox()
        Me.txtPass4 = New System.Windows.Forms.TextBox()
        CType(Me.numHerb, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.numKey, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.numCrypt, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.grpItem.SuspendLayout()
        Me.grpFlag.SuspendLayout()
        CType(Me.numGold, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.numExp, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'lblPass
        '
        Me.lblPass.AutoSize = True
        Me.lblPass.Location = New System.Drawing.Point(14, 18)
        Me.lblPass.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblPass.Name = "lblPass"
        Me.lblPass.Size = New System.Drawing.Size(109, 19)
        Me.lblPass.TabIndex = 0
        Me.lblPass.Text = "復活の呪文"
        '
        'txtPlayerName
        '
        Me.txtPlayerName.ImeMode = System.Windows.Forms.ImeMode.Hiragana
        Me.txtPlayerName.Location = New System.Drawing.Point(111, 141)
        Me.txtPlayerName.MaxLength = 4
        Me.txtPlayerName.Name = "txtPlayerName"
        Me.txtPlayerName.Size = New System.Drawing.Size(164, 26)
        Me.txtPlayerName.TabIndex = 10
        '
        'numHerb
        '
        Me.numHerb.Location = New System.Drawing.Point(112, 234)
        Me.numHerb.Maximum = New Decimal(New Integer() {6, 0, 0, 0})
        Me.numHerb.Name = "numHerb"
        Me.numHerb.Size = New System.Drawing.Size(163, 26)
        Me.numHerb.TabIndex = 16
        '
        'numKey
        '
        Me.numKey.Location = New System.Drawing.Point(112, 263)
        Me.numKey.Maximum = New Decimal(New Integer() {6, 0, 0, 0})
        Me.numKey.Name = "numKey"
        Me.numKey.Size = New System.Drawing.Size(163, 26)
        Me.numKey.TabIndex = 18
        '
        'cmbShield
        '
        Me.cmbShield.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbShield.FormattingEnabled = True
        Me.cmbShield.Location = New System.Drawing.Point(112, 371)
        Me.cmbShield.Name = "cmbShield"
        Me.cmbShield.Size = New System.Drawing.Size(163, 27)
        Me.cmbShield.TabIndex = 24
        '
        'cmbWeapon
        '
        Me.cmbWeapon.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbWeapon.FormattingEnabled = True
        Me.cmbWeapon.Location = New System.Drawing.Point(111, 300)
        Me.cmbWeapon.Name = "cmbWeapon"
        Me.cmbWeapon.Size = New System.Drawing.Size(164, 27)
        Me.cmbWeapon.TabIndex = 20
        '
        'cmbArmor
        '
        Me.cmbArmor.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbArmor.FormattingEnabled = True
        Me.cmbArmor.Location = New System.Drawing.Point(112, 338)
        Me.cmbArmor.Name = "cmbArmor"
        Me.cmbArmor.Size = New System.Drawing.Size(163, 27)
        Me.cmbArmor.TabIndex = 22
        '
        'cmbItem1
        '
        Me.cmbItem1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem1.FormattingEnabled = True
        Me.cmbItem1.Location = New System.Drawing.Point(25, 25)
        Me.cmbItem1.Name = "cmbItem1"
        Me.cmbItem1.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem1.TabIndex = 0
        '
        'cmbItem2
        '
        Me.cmbItem2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem2.FormattingEnabled = True
        Me.cmbItem2.Location = New System.Drawing.Point(25, 58)
        Me.cmbItem2.Name = "cmbItem2"
        Me.cmbItem2.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem2.TabIndex = 1
        '
        'cmbItem3
        '
        Me.cmbItem3.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem3.FormattingEnabled = True
        Me.cmbItem3.Location = New System.Drawing.Point(26, 91)
        Me.cmbItem3.Name = "cmbItem3"
        Me.cmbItem3.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem3.TabIndex = 2
        '
        'cmbItem6
        '
        Me.cmbItem6.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem6.FormattingEnabled = True
        Me.cmbItem6.Location = New System.Drawing.Point(27, 190)
        Me.cmbItem6.Name = "cmbItem6"
        Me.cmbItem6.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem6.TabIndex = 5
        '
        'cmbItem5
        '
        Me.cmbItem5.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem5.FormattingEnabled = True
        Me.cmbItem5.Location = New System.Drawing.Point(26, 157)
        Me.cmbItem5.Name = "cmbItem5"
        Me.cmbItem5.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem5.TabIndex = 4
        '
        'cmbItem4
        '
        Me.cmbItem4.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem4.FormattingEnabled = True
        Me.cmbItem4.Location = New System.Drawing.Point(26, 124)
        Me.cmbItem4.Name = "cmbItem4"
        Me.cmbItem4.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem4.TabIndex = 3
        '
        'cmbItem8
        '
        Me.cmbItem8.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem8.FormattingEnabled = True
        Me.cmbItem8.Location = New System.Drawing.Point(28, 256)
        Me.cmbItem8.Name = "cmbItem8"
        Me.cmbItem8.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem8.TabIndex = 7
        '
        'cmbItem7
        '
        Me.cmbItem7.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cmbItem7.FormattingEnabled = True
        Me.cmbItem7.Location = New System.Drawing.Point(27, 223)
        Me.cmbItem7.Name = "cmbItem7"
        Me.cmbItem7.Size = New System.Drawing.Size(169, 27)
        Me.cmbItem7.TabIndex = 6
        '
        'chkFlag1
        '
        Me.chkFlag1.AutoSize = True
        Me.chkFlag1.Location = New System.Drawing.Point(23, 25)
        Me.chkFlag1.Name = "chkFlag1"
        Me.chkFlag1.Size = New System.Drawing.Size(91, 16)
        Me.chkFlag1.TabIndex = 0
        Me.chkFlag1.Text = "竜の鱗を装備"
        Me.chkFlag1.UseVisualStyleBackColor = True
        '
        'chkFlag5
        '
        Me.chkFlag5.AutoSize = True
        Me.chkFlag5.Location = New System.Drawing.Point(23, 153)
        Me.chkFlag5.Name = "chkFlag5"
        Me.chkFlag5.Size = New System.Drawing.Size(111, 16)
        Me.chkFlag5.TabIndex = 4
        Me.chkFlag5.Text = "死の首飾りを入手"
        Me.chkFlag5.UseVisualStyleBackColor = True
        '
        'chkFlag4
        '
        Me.chkFlag4.AutoSize = True
        Me.chkFlag4.Location = New System.Drawing.Point(23, 121)
        Me.chkFlag4.Name = "chkFlag4"
        Me.chkFlag4.Size = New System.Drawing.Size(101, 16)
        Me.chkFlag4.TabIndex = 3
        Me.chkFlag4.Text = "ゴーレムを倒した"
        Me.chkFlag4.UseVisualStyleBackColor = True
        '
        'chkFlag3
        '
        Me.chkFlag3.AutoSize = True
        Me.chkFlag3.Location = New System.Drawing.Point(23, 89)
        Me.chkFlag3.Name = "chkFlag3"
        Me.chkFlag3.Size = New System.Drawing.Size(98, 16)
        Me.chkFlag3.TabIndex = 2
        Me.chkFlag3.Text = "ドラゴンを倒した"
        Me.chkFlag3.UseVisualStyleBackColor = True
        '
        'chkFlag2
        '
        Me.chkFlag2.AutoSize = True
        Me.chkFlag2.Location = New System.Drawing.Point(23, 57)
        Me.chkFlag2.Name = "chkFlag2"
        Me.chkFlag2.Size = New System.Drawing.Size(115, 16)
        Me.chkFlag2.TabIndex = 1
        Me.chkFlag2.Text = "戦士の腕輪を装備"
        Me.chkFlag2.UseVisualStyleBackColor = True
        '
        'numCrypt
        '
        Me.numCrypt.Location = New System.Drawing.Point(636, 324)
        Me.numCrypt.Maximum = New Decimal(New Integer() {7, 0, 0, 0})
        Me.numCrypt.Name = "numCrypt"
        Me.numCrypt.Size = New System.Drawing.Size(120, 26)
        Me.numCrypt.TabIndex = 28
        '
        'txtResult
        '
        Me.txtResult.Location = New System.Drawing.Point(636, 361)
        Me.txtResult.Name = "txtResult"
        Me.txtResult.ReadOnly = True
        Me.txtResult.Size = New System.Drawing.Size(120, 26)
        Me.txtResult.TabIndex = 30
        '
        'btnGetParam
        '
        Me.btnGetParam.Location = New System.Drawing.Point(131, 47)
        Me.btnGetParam.Name = "btnGetParam"
        Me.btnGetParam.Size = New System.Drawing.Size(144, 37)
        Me.btnGetParam.TabIndex = 5
        Me.btnGetParam.Text = "↓解析"
        Me.btnGetParam.UseVisualStyleBackColor = True
        '
        'btnGetPass
        '
        Me.btnGetPass.Location = New System.Drawing.Point(281, 47)
        Me.btnGetPass.Name = "btnGetPass"
        Me.btnGetPass.Size = New System.Drawing.Size(144, 39)
        Me.btnGetPass.TabIndex = 6
        Me.btnGetPass.Text = "↑生成"
        Me.btnGetPass.UseVisualStyleBackColor = True
        '
        'lblName
        '
        Me.lblName.AutoSize = True
        Me.lblName.Location = New System.Drawing.Point(14, 140)
        Me.lblName.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblName.Name = "lblName"
        Me.lblName.Size = New System.Drawing.Size(49, 19)
        Me.lblName.TabIndex = 9
        Me.lblName.Text = "名前"
        '
        'lblGold
        '
        Me.lblGold.AutoSize = True
        Me.lblGold.Location = New System.Drawing.Point(14, 169)
        Me.lblGold.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblGold.Name = "lblGold"
        Me.lblGold.Size = New System.Drawing.Size(69, 19)
        Me.lblGold.TabIndex = 11
        Me.lblGold.Text = "所持金"
        '
        'lblExp
        '
        Me.lblExp.AutoSize = True
        Me.lblExp.Location = New System.Drawing.Point(14, 199)
        Me.lblExp.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblExp.Name = "lblExp"
        Me.lblExp.Size = New System.Drawing.Size(69, 19)
        Me.lblExp.TabIndex = 13
        Me.lblExp.Text = "経験値"
        '
        'lblHerb
        '
        Me.lblHerb.AutoSize = True
        Me.lblHerb.Location = New System.Drawing.Point(14, 235)
        Me.lblHerb.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblHerb.Name = "lblHerb"
        Me.lblHerb.Size = New System.Drawing.Size(49, 19)
        Me.lblHerb.TabIndex = 15
        Me.lblHerb.Text = "薬草"
        '
        'lblKey
        '
        Me.lblKey.AutoSize = True
        Me.lblKey.Location = New System.Drawing.Point(14, 265)
        Me.lblKey.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblKey.Name = "lblKey"
        Me.lblKey.Size = New System.Drawing.Size(89, 19)
        Me.lblKey.TabIndex = 17
        Me.lblKey.Text = "魔法の鍵"
        '
        'lblWeapon
        '
        Me.lblWeapon.AutoSize = True
        Me.lblWeapon.Location = New System.Drawing.Point(14, 300)
        Me.lblWeapon.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblWeapon.Name = "lblWeapon"
        Me.lblWeapon.Size = New System.Drawing.Size(49, 19)
        Me.lblWeapon.TabIndex = 19
        Me.lblWeapon.Text = "武器"
        '
        'lblShield
        '
        Me.lblShield.AutoSize = True
        Me.lblShield.Location = New System.Drawing.Point(14, 374)
        Me.lblShield.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblShield.Name = "lblShield"
        Me.lblShield.Size = New System.Drawing.Size(29, 19)
        Me.lblShield.TabIndex = 23
        Me.lblShield.Text = "盾"
        '
        'lblArmor
        '
        Me.lblArmor.AutoSize = True
        Me.lblArmor.Location = New System.Drawing.Point(14, 338)
        Me.lblArmor.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblArmor.Name = "lblArmor"
        Me.lblArmor.Size = New System.Drawing.Size(29, 19)
        Me.lblArmor.TabIndex = 21
        Me.lblArmor.Text = "鎧"
        '
        'grpItem
        '
        Me.grpItem.Controls.Add(Me.cmbItem1)
        Me.grpItem.Controls.Add(Me.cmbItem2)
        Me.grpItem.Controls.Add(Me.cmbItem3)
        Me.grpItem.Controls.Add(Me.cmbItem4)
        Me.grpItem.Controls.Add(Me.cmbItem5)
        Me.grpItem.Controls.Add(Me.cmbItem6)
        Me.grpItem.Controls.Add(Me.cmbItem7)
        Me.grpItem.Controls.Add(Me.cmbItem8)
        Me.grpItem.Location = New System.Drawing.Point(298, 100)
        Me.grpItem.Name = "grpItem"
        Me.grpItem.Size = New System.Drawing.Size(217, 298)
        Me.grpItem.TabIndex = 25
        Me.grpItem.TabStop = False
        Me.grpItem.Text = "道具"
        '
        'grpFlag
        '
        Me.grpFlag.Controls.Add(Me.chkFlag1)
        Me.grpFlag.Controls.Add(Me.chkFlag5)
        Me.grpFlag.Controls.Add(Me.chkFlag4)
        Me.grpFlag.Controls.Add(Me.chkFlag3)
        Me.grpFlag.Controls.Add(Me.chkFlag2)
        Me.grpFlag.Location = New System.Drawing.Point(527, 102)
        Me.grpFlag.Name = "grpFlag"
        Me.grpFlag.Size = New System.Drawing.Size(251, 199)
        Me.grpFlag.TabIndex = 26
        Me.grpFlag.TabStop = False
        Me.grpFlag.Text = "フラグ"
        '
        'lblResult
        '
        Me.lblResult.AutoSize = True
        Me.lblResult.Location = New System.Drawing.Point(531, 364)
        Me.lblResult.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblResult.Name = "lblResult"
        Me.lblResult.Size = New System.Drawing.Size(89, 19)
        Me.lblResult.TabIndex = 29
        Me.lblResult.Text = "チェック"
        '
        'lblCrypt
        '
        Me.lblCrypt.AutoSize = True
        Me.lblCrypt.Location = New System.Drawing.Point(531, 322)
        Me.lblCrypt.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblCrypt.Name = "lblCrypt"
        Me.lblCrypt.Size = New System.Drawing.Size(69, 19)
        Me.lblCrypt.TabIndex = 27
        Me.lblCrypt.Text = "暗号化"
        '
        'txtLevel
        '
        Me.txtLevel.Location = New System.Drawing.Point(112, 109)
        Me.txtLevel.Name = "txtLevel"
        Me.txtLevel.ReadOnly = True
        Me.txtLevel.Size = New System.Drawing.Size(163, 26)
        Me.txtLevel.TabIndex = 8
        Me.txtLevel.Text = "1"
        '
        'lblLevel
        '
        Me.lblLevel.AutoSize = True
        Me.lblLevel.Location = New System.Drawing.Point(14, 112)
        Me.lblLevel.Margin = New System.Windows.Forms.Padding(5, 0, 5, 0)
        Me.lblLevel.Name = "lblLevel"
        Me.lblLevel.Size = New System.Drawing.Size(69, 19)
        Me.lblLevel.TabIndex = 7
        Me.lblLevel.Text = "レベル"
        '
        'numGold
        '
        Me.numGold.Location = New System.Drawing.Point(111, 173)
        Me.numGold.Maximum = New Decimal(New Integer() {65535, 0, 0, 0})
        Me.numGold.Name = "numGold"
        Me.numGold.Size = New System.Drawing.Size(164, 26)
        Me.numGold.TabIndex = 12
        '
        'numExp
        '
        Me.numExp.Location = New System.Drawing.Point(111, 205)
        Me.numExp.Maximum = New Decimal(New Integer() {65535, 0, 0, 0})
        Me.numExp.Name = "numExp"
        Me.numExp.Size = New System.Drawing.Size(164, 26)
        Me.numExp.TabIndex = 14
        '
        'txtPass1
        '
        Me.txtPass1.ImeMode = System.Windows.Forms.ImeMode.Hiragana
        Me.txtPass1.Location = New System.Drawing.Point(131, 11)
        Me.txtPass1.MaxLength = 5
        Me.txtPass1.Name = "txtPass1"
        Me.txtPass1.Size = New System.Drawing.Size(110, 26)
        Me.txtPass1.TabIndex = 1
        Me.txtPass1.Text = "ふるいけや"
        '
        'txtPass2
        '
        Me.txtPass2.ImeMode = System.Windows.Forms.ImeMode.Hiragana
        Me.txtPass2.Location = New System.Drawing.Point(247, 11)
        Me.txtPass2.MaxLength = 7
        Me.txtPass2.Name = "txtPass2"
        Me.txtPass2.Size = New System.Drawing.Size(157, 26)
        Me.txtPass2.TabIndex = 2
        Me.txtPass2.Text = "かわずとびこむ"
        '
        'txtPass3
        '
        Me.txtPass3.ImeMode = System.Windows.Forms.ImeMode.Hiragana
        Me.txtPass3.Location = New System.Drawing.Point(410, 11)
        Me.txtPass3.MaxLength = 5
        Me.txtPass3.Name = "txtPass3"
        Me.txtPass3.Size = New System.Drawing.Size(110, 26)
        Me.txtPass3.TabIndex = 3
        Me.txtPass3.Text = "みずのおと"
        '
        'txtPass4
        '
        Me.txtPass4.ImeMode = System.Windows.Forms.ImeMode.Hiragana
        Me.txtPass4.Location = New System.Drawing.Point(525, 11)
        Me.txtPass4.MaxLength = 3
        Me.txtPass4.Name = "txtPass4"
        Me.txtPass4.Size = New System.Drawing.Size(70, 26)
        Me.txtPass4.TabIndex = 4
        Me.txtPass4.Text = "ばしや"
        '
        'FrmDq1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(10.0!, 19.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer))
        Me.ClientSize = New System.Drawing.Size(800, 417)
        Me.Controls.Add(Me.txtPass4)
        Me.Controls.Add(Me.txtPass3)
        Me.Controls.Add(Me.txtPass2)
        Me.Controls.Add(Me.txtPass1)
        Me.Controls.Add(Me.numExp)
        Me.Controls.Add(Me.numGold)
        Me.Controls.Add(Me.lblLevel)
        Me.Controls.Add(Me.lblResult)
        Me.Controls.Add(Me.lblCrypt)
        Me.Controls.Add(Me.grpFlag)
        Me.Controls.Add(Me.grpItem)
        Me.Controls.Add(Me.lblArmor)
        Me.Controls.Add(Me.lblShield)
        Me.Controls.Add(Me.lblWeapon)
        Me.Controls.Add(Me.lblKey)
        Me.Controls.Add(Me.lblHerb)
        Me.Controls.Add(Me.lblExp)
        Me.Controls.Add(Me.lblGold)
        Me.Controls.Add(Me.lblName)
        Me.Controls.Add(Me.btnGetPass)
        Me.Controls.Add(Me.btnGetParam)
        Me.Controls.Add(Me.cmbArmor)
        Me.Controls.Add(Me.cmbWeapon)
        Me.Controls.Add(Me.cmbShield)
        Me.Controls.Add(Me.numKey)
        Me.Controls.Add(Me.numCrypt)
        Me.Controls.Add(Me.numHerb)
        Me.Controls.Add(Me.txtLevel)
        Me.Controls.Add(Me.txtResult)
        Me.Controls.Add(Me.txtPlayerName)
        Me.Controls.Add(Me.lblPass)
        Me.Font = New System.Drawing.Font("MS ゴシック", 14.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(128, Byte))
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        Me.Margin = New System.Windows.Forms.Padding(5)
        Me.MaximizeBox = False
        Me.Name = "FrmDq1"
        Me.Text = "DQ1 - 復活の呪文解析ツール"
        CType(Me.numHerb, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.numKey, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.numCrypt, System.ComponentModel.ISupportInitialize).EndInit()
        Me.grpItem.ResumeLayout(False)
        Me.grpFlag.ResumeLayout(False)
        Me.grpFlag.PerformLayout()
        CType(Me.numGold, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.numExp, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub
    Friend WithEvents lblPass As System.Windows.Forms.Label
    Friend WithEvents txtPlayerName As System.Windows.Forms.TextBox
    Friend WithEvents numHerb As System.Windows.Forms.NumericUpDown
    Friend WithEvents numKey As System.Windows.Forms.NumericUpDown
    Friend WithEvents cmbShield As System.Windows.Forms.ComboBox
    Friend WithEvents cmbWeapon As System.Windows.Forms.ComboBox
    Friend WithEvents cmbArmor As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem1 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem2 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem3 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem6 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem5 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem4 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem8 As System.Windows.Forms.ComboBox
    Friend WithEvents cmbItem7 As System.Windows.Forms.ComboBox
    Friend WithEvents chkFlag1 As System.Windows.Forms.CheckBox
    Friend WithEvents chkFlag5 As System.Windows.Forms.CheckBox
    Friend WithEvents chkFlag4 As System.Windows.Forms.CheckBox
    Friend WithEvents chkFlag3 As System.Windows.Forms.CheckBox
    Friend WithEvents chkFlag2 As System.Windows.Forms.CheckBox
    Friend WithEvents numCrypt As System.Windows.Forms.NumericUpDown
    Friend WithEvents txtResult As System.Windows.Forms.TextBox
    Friend WithEvents btnGetParam As System.Windows.Forms.Button
    Friend WithEvents btnGetPass As System.Windows.Forms.Button
    Friend WithEvents lblName As System.Windows.Forms.Label
    Friend WithEvents lblGold As System.Windows.Forms.Label
    Friend WithEvents lblExp As System.Windows.Forms.Label
    Friend WithEvents lblHerb As System.Windows.Forms.Label
    Friend WithEvents lblKey As System.Windows.Forms.Label
    Friend WithEvents lblWeapon As System.Windows.Forms.Label
    Friend WithEvents lblShield As System.Windows.Forms.Label
    Friend WithEvents lblArmor As System.Windows.Forms.Label
    Friend WithEvents grpItem As System.Windows.Forms.GroupBox
    Friend WithEvents grpFlag As System.Windows.Forms.GroupBox
    Friend WithEvents lblResult As System.Windows.Forms.Label
    Friend WithEvents lblCrypt As System.Windows.Forms.Label
    Friend WithEvents txtLevel As System.Windows.Forms.TextBox
    Friend WithEvents lblLevel As System.Windows.Forms.Label
    Friend WithEvents numGold As System.Windows.Forms.NumericUpDown
    Friend WithEvents numExp As System.Windows.Forms.NumericUpDown
    Friend WithEvents txtPass1 As System.Windows.Forms.TextBox
    Friend WithEvents txtPass2 As System.Windows.Forms.TextBox
    Friend WithEvents txtPass3 As System.Windows.Forms.TextBox
    Friend WithEvents txtPass4 As System.Windows.Forms.TextBox

End Class
[VB.NET]FrmDq1.Designer.vb


[雑記]ドローン(DJI Mini 3)

(1)雑記 もともと多趣味の友人 masakazu Drone 氏が、 最近、 ドローン にハマり始めて、 更に、新たな趣味が増えたとのこと。 ドローン を始めてから、 まだ1年も経っていないとのことですが、 旅行先で山や川の景色を 空撮 して、 Youtube ...