データサービス事業
  オープンテクノロジー(Red Bible)
  パッケージ事業
  SI事業




≪Red Bible≫
  ブラウザ自動操作
  ExcelVBAソースの可視化
  AccessMDBの可視化
  C#プロジェクトソースの可視化
  ExcelをWebクライアントにする NEW! 

≪データサービス≫
  新設法人データ(確報版)
  新設法人データ(速報版)

≪パッケージ≫
  登記データ自動取得プログラム
  新設法人データ自動取得プログラム
  OCR文書管理プログラム

≪サービス≫
  OCRデータエントリーサービス
  登記データ取得代行サービス
  Webデータ情報収集サービス

≪システムインテグレーションサービス≫
  Webシステム業務運用改善技術
  Webクローリングシステム
  IT資産分析サービス
  モデリングサービス(リエンジニアリング)
  レガシーコンバージョンサービス事例
  OCRエントリーシステム構築

≪会社情報≫
  会社情報

≪お問い合わせ≫
  お問い合わせはコチラ
C#ソースコードの可視化
概要
 C#プログラムの可視化 

 §4   ビジネステクノロジー活用講座

■C#のソースコードを可視化/一覧化する

COBOLやPL/Iなどのレガシーコードの可視化はよく目にしますが、時代の先端を行くJavaやC#、実はこれらのオブジェクト指向言語で 書かれたシステム/プログラムもソースの可読性という点からみると、レガシーコードより読みにくいのが現実です。 実はこれらのプログラムはリバース、解析するにしても、レガシーコードやVBAなどより厄介です。 "function"や"sub"のような単純キーワードだけでは解析できません。プログラミングの文法に従って、ソースコードを解析していく必要があります。
とはいえ、C#の全ソースコードをExcelシート上に集めて解析したい場合が往々にあります。 ここではそのC#のプログラム解析を行うプログラムの一部を紹介します。

☆解析用の全ソースが必要な方は別途お問い合わせください☆


解析し、Excelシート上に取り込んだC#ソース一覧

Excelに取り込んで文法に従って解析し、クラス一覧を作成

詳細解析を行い、メソッド一覧を作成

ソースステートメントを解析し、メソッド呼び出し部分を抽出したメソッド呼出し一覧

メソッド呼出し一覧から呼び出しネスト図を作成


【C#プログラムの可視化プログラム・ソース(抜粋)】



'基本解析
Private Sub prog0()
    Dim FN As String
    Dim FNP As String
    Dim FNL As String
    Dim FNLV As Variant
        
    Dim buff, buffx As String
    Dim eofflg, comflg As Integer
    Dim outcode, outcom As Long
    Dim lmax As Long
    Dim x, x1 As String
    Dim stmtno, stmtno0 As Long
    Dim linepos As Long
    Dim colpos As Long
    
    Dim org As Long
            
    Dim idx1 As Long
    
    Dim Seq_No As Long  '全体通し番号
    
    Dim LT1, LT2, KA1 As Long 'リテラルや()の出現回数
        
    org = 1
    
    'クリアー
    Worksheets("ORG").Cells.ClearContents
    Worksheets("コード").Cells.ClearContents
    Worksheets("コメント").Cells.ClearContents
    
    Seq_No = 0
    
    'ファイルを読み込むための配列
    Dim Arr()
    'ReDim Preserve Arr(0)
    Dim ftxtobj As Object
                    
    'ファイル共通初期化
    outcode = 1
    outcom = 1

    'GET FOLDER NAME
    'FNP = GetFoldername("C:")
    FNP = GetFoldername("")
    
    'Get File Name List
    FNL = getFileList(FNP)
    'List分解
    FNLV = Split(FNL, ",")
   
    'DO FOR ALL FILES
    idx1 = 0
    Do While idx1 <= UBound(FNLV)
      'select source file
      FN = FNLV(idx1)
      GoSub fileproc
      idx1 = idx1 + 1
    Loop
            
    'Make Namespace ID
    GoSub namespacecnt
    
    MsgBox ("基本解析終了")
    
    Exit Sub
    
 
'ファイル単位の処理
fileproc:

    '入力ファイルのOpen
    GoSub fn00
    
    buff = ""
    eofflg = 0
    linepos = 0
    comflg = 0
    stmtno = 0
    stmtno0 = 0
    
    
    '出現回数カウンタ=0
    LT1 = 0
    LT2 = 0
    KA1 = 0
    
l00:
    'Buffが空ならば次を読む
    If buff = "" Then
      If eofflg = 1 Then
        'EOFFLGならば終了
        GoTo l99
      Else
        '1行読み取り(Buff,LinePos)、有効文字までスキップ(ColPos)
        If ftxtobj.EOS Then
          eofflg = 1
          buff = ""
          linepos = linepos + 1
        Else
          'read
          buff = ftxtobj.ReadText(-2)  'adReadLine
          stmtno = stmtno + 1   '現在行
          stmtno0 = stmtno      '開始行
                    
          Worksheets("ORG").Cells(org, 1) = buff
          org = org + 1
          
          buff = LTrim(buff)
          buff = Replace(buff, Chr(9), " ")
          DoEvents
          colpos = 1
         
        End If
      End If
    End If
    
    'if コメントの開始(/*)ならばコメント開始
    If Left(buff, 2) = "/*" Then
      comflg = 1
    End If

    If comflg = 1 Then
      'if コメント中ならば
      'コメントの終了*/または改行までを1ステートメントとして出力
      lmax = Len(buff)
      Do Until colpos > lmax
        If Mid(buff, colpos, 2) = "*/" Then
          comflg = 0
          outcom = outcom + 1
          Worksheets("コメント").Cells(outcom, 1) = stmtno0
          Worksheets("コメント").Cells(outcom, 4) = Left(buff, colpos + 1)
          Worksheets("コメント").Cells(outcom, 5) = FN
          Worksheets("コメント").Cells(outcom, 6) = Seq_No
          buff = Mid(buff, colpos + 2, 10000)
          GoTo l00
        End If
        colpos = colpos + 1
      Loop
      '行終わりまで
      outcom = outcom + 1
      Worksheets("コメント").Cells(outcom, 1) = stmtno0
      Worksheets("コメント").Cells(outcom, 4) = Left(buff, 10000)
      Worksheets("コメント").Cells(outcom, 5) = FN
      Worksheets("コメント").Cells(outcom, 6) = Seq_No
      buff = ""
      GoTo l00
    End If

    'if コメント行開始(//)
    If Left(buff, 2) = "//" Then
      outcom = outcom + 1
      Worksheets("コメント").Cells(outcom, 1) = stmtno0
      Worksheets("コメント").Cells(outcom, 4) = Left(buff, 10000)
      Worksheets("コメント").Cells(outcom, 5) = FN
      Worksheets("コメント").Cells(outcom, 6) = Seq_No
      buff = ""
      GoTo l00
    End If

    'STMT文字の処理
    '終了位置デリミターを見つける({,},;,EOF,//,/*)(LineDel,ColDel)
    'ただし、"'のリテラルや()の中は除く
    lmax = Len(buff)
    Do Until colpos > lmax
        x = Mid(buff, colpos, 1)
        x1 = Mid(buff, colpos, 2)
          
          If LT1 > 0 Or LT2 > 0 Then
            If LT1 > 0 And x1 <> "''" And x = "'" Then
              LT1 = LT1 - 1
            End If
            If LT2 > 0 And x1 <> """""" And x = """" Then
              LT2 = LT2 - 1
            End If
            
          Else
            If x = "'" Then
              LT1 = LT1 + 1
              GoTo skp01
            Else
              If x = """" Then
                LT2 = LT2 + 1
                GoTo skp01
              End If
            End If
            
            If x = ")" Then
              KA1 = KA1 - 1
              If KA1 < 0 Then
                KA1 = 0
                MsgBox ("()の数不正 " & CStr(Seq_No))
              End If
            Else
              If x = "(" Then
                KA1 = KA1 + 1
              End If
            End If
            
            If (x = "{" And KA1 = 0) Or (x = "}" And KA1 = 0) Or (x = ";" And KA1 = 0) Or x1 = "//" Or x = "/*" Or eofflg = 1 Then
            
              'コード出力
              If Trim(Left(buff, colpos - 1)) <> "" Then
                outcode = outcode + 1
                Seq_No = Seq_No + 1
                Worksheets("コード").Cells(outcode, 1) = stmtno0
                Worksheets("コード").Cells(outcode, 3) = "C"
                Worksheets("コード").Cells(outcode, 4) = TrimAll(Left(buff, colpos - 1))
                Worksheets("コード").Cells(outcode, 7) = FN
                Worksheets("コード").Cells(outcode, 20) = Seq_No
              End If
              'デリミタ出力
              If x1 = "//" Or x = "/*" Or eofflg = 1 Then
                '出力しない
              Else
                outcode = outcode + 1
                Seq_No = Seq_No + 1
                Worksheets("コード").Cells(outcode, 1) = stmtno
                Worksheets("コード").Cells(outcode, 3) = "D"
                Worksheets("コード").Cells(outcode, 4) = TrimAll(x)
                Worksheets("コード").Cells(outcode, 7) = FN
                Worksheets("コード").Cells(outcode, 20) = Seq_No
              End If
              '残りをセット
              If x1 = "//" Or x = "/*" Then
                buff = LTrim(Mid(buff, colpos, 10000))
              Else
                buff = LTrim(Mid(buff, colpos + 1, 10000))
              End If
              colpos = 1
                             
              '出現回数カウンタ=0
              LT1 = 0
              LT2 = 0
              KA1 = 0
              
              GoTo l00
            End If
          End If
skp01:
        colpos = colpos + 1
    Loop
    '行終わりまでなし、継続
    If eofflg = 1 Then GoTo l99 'すでになら終了
    If ftxtobj.EOS Then
      eofflg = 1
    Else
      'read
      buffx = ftxtobj.ReadText(-2)  'adReadLine
      
                          
          Worksheets("ORG").Cells(org, 1) = buffx
          org = org + 1
          
      
      If buff = "" Then
        stmtno = stmtno + 1
        stmtno0 = stmtno
      Else
        stmtno = stmtno + 1
      End If
      buff = buff & " " & buffx
      buff = Replace(buff, Chr(9), " ")
      DoEvents
    End If
    GoTo l00
    
l99:
    outcode = outcode + 1
    Seq_No = Seq_No + 1
    Worksheets("コード").Cells(outcode, 1) = "99999999"
    Worksheets("コード").Cells(outcode, 3) = "D"
    Worksheets("コード").Cells(outcode, 4) = "[EOF]"
    Worksheets("コード").Cells(outcode, 7) = FN
    Worksheets("コード").Cells(outcode, 20) = Seq_No
    GoSub fn99    'ファイルのクローズ
    Return
   
    
    
'ファイルのオープン
fn00:
    'ファイルオープンと取得
    'オブジェクトを作成
    Set ftxtobj = CreateObject("ADODB.Stream")
    'オブジェクトに保存するデータの種類を文字列型に指定する
    ftxtobj.Type = 2 'adTypeText
    '文字コードを取得し、設定する
    ftxtobj.Charset = GetEncodeType(FNP & "\" & FN)
    'オブジェクトのインスタンスを作成
    ftxtobj.Open
    'ファイルからデータを読み込む
    ftxtobj.LoadFromFile (FNP & "\" & FN)
    Return


'ファイルのクローズ
fn99:
    'オブジェクトを閉じる
    ftxtobj.Close
    'メモリからオブジェクトを削除する
    Set ftxtobj = Nothing
    Return
    
'名前空間、変数領域IDの設定
namespacecnt:
    Dim sid As String
    Dim scope1, scope2(100) As Integer
    Dim i, idx As Long
    scope1 = 0
    For i = 1 To 100
      scope2(i) = 0
    Next i
    idx = 2
    sid = "コード"
    Do Until Worksheets(sid).Cells(idx, 1) = ""
      If Worksheets(sid).Cells(idx, 3) = "D" Then
        If Worksheets(sid).Cells(idx, 4) = "{" Then
          scope1 = scope1 + 1
          If scope1 > 98 Then
            MsgBox ("Scope level exceeds 98 ")
            Exit Sub
          End If
          scope2(scope1) = scope2(scope1) + 1
          GoSub setlvl
        Else
          If Worksheets(sid).Cells(idx, 4) = "}" Then
            GoSub setlvl
            scope1 = scope1 - 1
            '強制アジャスト
            If scope1 < 0 Then
              scope1 = 0
            End If
            '
            For i = scope1 + 2 To 100
              scope2(i) = 0
            Next i
          Else
            GoSub setlvl
          End If
        End If
      Else
        GoSub setlvl
      End If
      idx = idx + 1
    Loop
    Return
    
setlvl:
    If Worksheets(sid).Cells(idx, 4) = "[EOF]" Then
      '強制リセット
      scope1 = 0
      For i = 1 To 100
        scope2(i) = 0
      Next i
    End If
    
    Return
    
End Sub


Excelシートに取り込めば、あとはExcelの検索やフィルタ機能、さらにはVBAを使えば本格的なプログラム解析まで簡単に可能です。 システムエンジニアの手作業に依存せず、エンジニアよりも安く、早く、正確に作業が可能です。ぜひお試しください。