[[20200818220327]] 『相関図をデータから自動生成する方法について』(ふなはし) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『相関図をデータから自動生成する方法について』(ふなはし)

■やりたいこと
お客様の商流を相関図にしたい

■ご教授頂きたいこと
表形式にまとめた会社と会社のつながりから、相関図に展開する方法や自動生成するマクロを教えて頂きたいです。相関図とは、図形や┰や┗(けいせん)のテキストで関係が分かるような図で構いません。

例えば、下記の表を作ったら、下記の相関図を自動生成する。

【表】
会社1  会社2
A社   C社
B社   D社
A社   D社
C社   E社
A社   E社

【相関図】
┌──────┐
A社┰C社─E社
  ┃
B社┻D社

以上、よろしくお願い致します。

< 使用 Excel:Excel2007、使用 OS:Windows7 >


組織図やフローチャートの部類になるので
https://excel-master.net/graphics/organization-chart/
を参考に作成したらどうですか。
それだけのものマクロにする必要はないと思いますが。
(SOH) 2020/08/19(水) 09:23

相関図から推して、A社とD社が相関があるのなら、B社とC社も相関してそうだが、表には記載されていない?
(mm) 2020/08/19(水) 09:29

 昔、余所の掲示板で、同じテーマを扱ったことがあります。
      ↓
 ExcelQ&Aサロン
https://excelfactory.net/excelboard/excelvba/excel.cgi
 キーワード検索
 「会社のつながり・関係性を把握したい」

 ※ 過去ログ26 ● 内に入っています

(半平太) 2020/08/19(水) 09:54


まず、全ての会社名をそれぞれ1つのテキストボックスとして貼り付け。
その後、相関関係に従い、テキストボックス同士を線(ConnectorFormat)で連結すれば良いかと思います。

連結してしまえばテキストボックスの移動に合わせて線は移動するので、レイアウトは手作業で十分でしょう。 必要な命令やプロパティはマクロの記録機能で得られるので、後は頑張ってください。
(???) 2020/08/19(水) 10:11


 そうでした。昔やったことがありますね。
 過去ログ27(ですね)を 
 161833というキーワードで検索しても出てきます。

 この手の自動グラフ作成に関しては、
 GraphVizという定番のツールがあります。
 そのデータをもとに書かせてみたら、
 概略下記のような有向グラフ(図形)を、
 jpgファイルとして作成してくれました。
 (もちろん他のファイル形式も可です。)

            A社       B社
        ↙    ↓    ↘   ↓
     C社     ↓       D社
         ↘   ↓
            E社

 GraphVizの中のDOT言語というのがこれに合うんじゃないかな。
 GraphVizというのはAT&T研究所が2000年代初頭に開発した優れもので、
 現在でもこれを上回るものはないんじゃないかな。
 データサイエンスなどの領域でも現役で使われていると思います。

 Windows用のDLLファイルも提供されていて、VBAから利用することが
 できます。

 そのスレッドで提示しましたが、
 これからさらに図形情報をテキストに吐かせて、
 これを元にワークシートに図形を書くマクロを作りました。

 位置関係が複雑になると、とても自前のコードでは太刀打ちできないと
 思います。深い研究の成果を利用させてもらうのが得策だと思います。

 少し手を入れたものをアップしてもよいです。

(γ) 2020/08/19(水) 10:32


 皆さんご指摘のように、作業内容によりますね。
 大した数が無いのであれば、手作業が簡単だし、
 手作業であれば、気が済むまで、修正を加えることができると思います。

 以下、成り行きで、余談ぎみに、GraphVizの紹介をしておきましょう。

 活用例から入った方がよいかも。
https://graphviz.org/gallery/
 が参考になるでしょう。
https://graphviz.org/  がHome siteです。

 VBAから操作する一例として、
 下記にコードを提示しておきます。参考にしてください。

 ■設定
 (1)元データは、Sheet1のA,B列に書いておきます。(C列はブランクにしておいてください)
 (2)結果は、
     ・jpgファイル
     ・Sheet2に図形を使った描画
    の二つです。
 (3)もし、動作させてみたい方がおられたら、コードの最初に入手先も書きましたが、
    WinGraphviz.dllファイルが必要です。それを参照設定しておいて下さい。
 (4)マクロmainを実行します。

 ■参考コード =====================================
 Option Explicit

 ' Graphviz を使った企業関連図の作成
 '  【■環境設定】
 '   http://wingraphviz.sourceforge.net/wingraphviz/
 '   にある  WinGraphviz_v1.02.24.msi  のインストールが必要です。
 '   それを実行して得られるWinGraphviz.dllを参照設定します。
 '
 ' Sheet1のA列、B列にある元データを使って、Sheet2に相関図を描画します。

 Dim wsData As Worksheet, wsG As Worksheet
 Dim dic2 As Object
 Dim myHeight As Double  '(GraphVizでの)図形描画領域の高さ
 Const myScale As Long = 100

 Sub main()
     Dim dot As Object
     Dim img
     Dim k As Long
     Dim s1 As String, s2 As String
     Dim strCMD As String
     Dim text As String
     Dim s As String
     Dim mylines

     Set wsData = Worksheets("Sheet1")   ''■ 元データ
     Set wsG = Worksheets("Sheet2")      ''■ 変換後データがここに書き込まれ、
                                         ''   ここに描画します。
     Set dic2 = CreateObject("Scripting.Dictionary")

     '(0)図形シートの図形を初期化
     Dim shp As Shape
     For Each shp In wsG.Shapes
         shp.Delete
     Next

     '(1)Sheet1のデータを変換したものを、Sheet2に書きます。
     Call データ変換

     '(2) DOT言語のための文字列strCMDを作成 ---------------------------
     strCMD = "digraph G {charset=""UTF-8"";   " & vbCrLf

     'Edgeの指定
     For k = 2 To wsG.Cells(Rows.Count, 1).End(xlUp).Row
         s1 = wsG.Cells(k, 1).Value          ' 親会社(ラベル)
         s2 = wsG.Cells(k, 2).Value          ' 子会社(ラベル)
         strCMD = strCMD & " " _
                & s1 & " -> " & s2 & " [ dir=forward ] ; " & vbCrLf
                'jpgは正当な矢じり。Excel図は矢印とnodeとの間隔が若干空く。
 '        strCMD = strCMD & " " _
 '               & s1 & " -> " & s2 & " [dir=forward,arrowhead=none] ; " & vbCrLf 
                'jpgは矢じりなし。Excel図は矢印の位置とnodeの位置がぴったり一致。
     Next

     'nodeの指定
     For k = 2 To wsG.Cells(Rows.Count, 4).End(xlUp).Row
         s1 = wsG.Cells(k, 4).Value          'ラベル    (n1,n2,・・・)
         s2 = wsG.Cells(k, 5).Value          'ラベル名称(正式企業名)
         strCMD = strCMD & " " _
            & s1 & " [shape = ""box"" , height=.25 , label=""" & s2 & """" _
            & " , fontname=""MS ゴシック""]  " & vbCrLf
     Next

     strCMD = strCMD & "}"
     '''Debug.Print strCMD

     '(3)JPEG の作成 (GraphVizを利用して描画)-------------------------
     Set dot = CreateObject("Wingraphviz.dot")

     Set img = dot.ToJPEG(strCMD)
     img.Save "graph.jpg"

     '(4)Excelシートにやっぱり図形で描画したいよね。---------------------
     'そのための描画情報をGraphVizに書き出させる
     text = dot.ToPlain(strCMD)
     '''Debug.Print text

     'その情報に基づき、Excelに図形を描画
     mylines = Split(text, vbCr)
     s = mylines(0)
     myHeight = Split(s, " ")(3)     '画像の高さ(y座標変換のために必要)

     For k = 1 To UBound(mylines)
         s = mylines(k)
         If InStr(s, "node") > 0 Then
             node_plot s             ' node(企業名)の表示
         ElseIf InStr(s, "edge") > 0 Then
             edge_plot s             ' edge(関係)の表示
         End If
     Next

     '不要となった作業用文字列を消去
     wsG.Cells.ClearContents
 End Sub

 Private Sub データ変換()
     'WinGraphVizのDOT言語におけるnode名が日本語対応していないようなので、
     'いったんn1,n2,n3・・・といった仮node名に読み替える作業を行う。
     'ws2シートをそのための作業用に使用。

     Dim dic As Object
     Dim myRange As Range, myRange2 As Range
     Dim r As Range
     Dim s As String
     Dim k As Long
     Dim key

     Set dic = CreateObject("Scripting.Dictionary")

     Set myRange = wsData.Cells(1, 1).CurrentRegion

     '登場する企業名(node名)をいったん n1,n2,・・・に対応づける
     For Each r In myRange
         s = r.text
         If Not dic.exists(s) Then
             k = k + 1
             dic(s) = "n" & k
         End If
     Next

     wsG.Cells.ClearContents

     wsG.Cells(1, 1).Resize(1, 5).Value = Array("親", "子", "", "ラベル", "ラベル名称")
                         'D列(ラベル)はn1,n2,n3・・・。E列(ラベル名称)は当初の企業名
     myRange.Copy wsG.Cells(2, 1)
     Set myRange2 = wsG.Cells(2, 1).CurrentRegion

     '対応表をn1,n2,・・・で書換え
     For Each key In dic.keys
         myRange2.Replace key, dic(key), xlWhole
     Next

     '新旧の対応表をまとめる
     wsG.Cells(2, "D").Resize(dic.Count, 1) = Application.Transpose(dic.Items)
     wsG.Cells(2, "E").Resize(dic.Count, 1) = Application.Transpose(dic.keys)

 End Sub

 'GraphVizの図形情報テキスト(の一行s)をもとに、node図形をシートに描画
 Function node_plot(s As String) '
     Dim l As Double, t As Double, w As Double, h As Double, label As String
     Dim shp As Shape
     Dim a

     a = Split(s, " ")

     l = CDbl(a(3))  'nodeの中心のx座標
     t = CDbl(a(4))  'nodeの中心のy座標
     w = CDbl(a(5))  '幅
     h = CDbl(a(6))  '高さ

     label = Replace(a(7), """", "")
     dic2(a(1)) = t

     '長方形で描画(GraphVizのY座標は上ほど大きい数値。(Excelと逆なので注意))
     Set shp = wsG.Shapes.AddShape(msoShapeRectangle, _
                  (l - w / 2) * myScale, (myHeight - (t + h / 2)) * myScale, _
                  w * myScale, h * myScale)

     ' 楕円で描画
     'Set shp = wsG.Shapes.AddShape(msoShapeOval, _
     '    (l - w / 2) * myScale, (myHeight - (t + h / 2)) * myScale, _
     '     w * myScale, h * myScale)

     shp.TextFrame2.TextRange.Characters.text = label
     shp.TextFrame2.TextRange.Font.Size = 9
 End Function

 'GraphVizの図形情報テキスト(の一行s)をもとに、edge図形をシートに描画
 Function edge_plot(s As String)
     Dim a
     Dim num As Long
     Dim x() As Double
     Dim y() As Double
     Dim k As Long
     Dim j As Long
     Dim n As Long
     Dim shp As Shape

     a = Split(s, " ")
     num = a(3)      '辺を表すための点の数(通常は4,時に7や10。)

     ReDim x(1 To num) As Double
     ReDim y(1 To num) As Double

     For k = 1 To num
         x(k) = a(4 + 2 * (k - 1)) * myScale     ' myScaleはサイズの調整
         y(k) = (myHeight - a(5 + 2 * (k - 1))) * myScale
         ' y座標の方向が上下逆なので、それを調整
     Next

     '本来はB-Splineを使うべきだが、Excelのフリーフォームで代用
     With wsG.Shapes.BuildFreeform(msoEditingAuto, x(1), y(1))
         For j = 1 To (num - 1) \ 3
             n = 3 * (j - 1)
             .AddNodes msoSegmentCurve, msoEditingAuto, x(n + 2), y(n + 2), _
                      x(n + 3), y(n + 3), x(n + 4), y(n + 4)
         Next
         Set shp = .ConvertToShape
     End With

     shp.Line.Weight = 2.25      '線の太さ

     '矢印の向きを調整
     If dic2(a(1)) > dic2(a(2)) Then
         shp.Line.EndArrowheadStyle = msoArrowheadTriangle
     Else
         shp.Line.BeginArrowheadStyle = msoArrowheadTriangle
     End If
 End Function

(γ) 2020/08/19(水) 11:39


Sub main()
'表:Sheet1のA1="会社1",B1="会社2",A2="A社",B2="C社"…下行に続く
'相関図:Sheet2に作成
    Dim p As Double, x As Double, dic As Object, dic2 As Object, dt, ws1 As Worksheet, ws2 As Worksheet, ctr As Long, i As Long, c As Range, shp As Shape
    p = 3.14159265
    Set ws1 = Sheets("Sheet1")
    Set ws2 = Sheets("Sheet2")
    Set dic = CreateObject("Scripting.Dictionary")
    Set dic2 = CreateObject("Scripting.Dictionary")
    For Each c In ws1.Range("A2:B" & Rows.Count).SpecialCells(2)
    If Not dic.exists(c.Value) Then i = i + 1: dic(c.Value) = i: dic2(i) = c.Value
    Next c
    For Each shp In ws2.Shapes
        shp.Delete
    Next shp
    ctr = dic.Count
    ReDim dt(ctr, 1)
    For i = 1 To ctr
        dt(i, 0) = ws2.Range("f10").Left + 100 * Cos(x)
        dt(i, 1) = ws2.Range("f10").Top + 100 * Sin(x)
        With ws2.Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
            Left:=dt(i, 0), Top:=dt(i, 1), _
            Width:=40, Height:=20)
            .TextFrame.Characters.Font.Size = 10
            .TextFrame.Characters.Text = dic2(i)
            .Line.ForeColor.RGB = RGB(0, 0, 0)
        End With
        x = x + 2 * p / ctr
    Next i
    For Each c In ws1.Range("A2:A" & Rows.Count).SpecialCells(2)
        With ws2.Shapes.AddConnector(msoConnectorStraight, dt(dic(c.Value), 0), dt(dic(c.Value), 1), dt(dic(c.Offset(, 1).Value), 0), dt(dic(c.Offset(, 1).Value), 1))
            .Line.DashStyle = msoLineDash
            .Line.ForeColor.RGB = RGB(255, 0, 0)
        End With
    Next c
End Sub
(mm) 2020/08/19(水) 13:41

皆さまコメントありがとうございます。
質問時の説明がおおまかで申し訳ありませんでしたが、
一番の目的が、会社名で検索すれば、商流(各会社の関係)を誰でも瞬時に確認できるような仕組みを考えてます(会社は500社ほど)。担当以外の事務の人間や、引き継ぎ資料としての利用ですり

(SOH)様
参考URLご紹介ありがとうございます。
見てみます。

(mm)様
B社とC社は口座が無く、商流(相関)が無いことがありえます。
またコードもありがとうございます。
【誰でも】表さえメンテすればOKな仕組みがベストなので、実現難しいかもしれませんが、参考にします。

(半平太)様
確認します。ありがとうございます。

(???)様
コメントありがとうございます。
以下の理由で断念しました。
・会社数が約500社ほどまとめたく、テキストボックスだと手間
・テキスト検索して瞬時に把握できるようにしたい

(γ)様
ツール紹介、詳細にありがとうございます。
探していたことに一番近いため試しにやってみます。

(ふなはし) 2020/08/19(水) 20:02


(γ)様
過去ログ拝見しました。
会社PCがシンクラのためGraphvizのダウンロードにアドミン権限必要で、
営業職の私では無理でした。
一度、私物のPCのwin10、Excel2016でご教授頂いたソース試してみます。
私があまりPCに精通していないため、不明点出てきましたら
またご質問させて頂きます。
宜しくお願い致しますの
(ふなはし) 2020/08/19(水) 23:00

>一番の目的が、会社名で検索すれば、商流(各会社の関係)を誰でも
>瞬時に確認できるような仕組み
ということなら視覚化というよりも、テキストベースで考える方が先でしょう。
一足飛びにグラフ化したところで、検索が容易にできるというものでもないでしょう。
 
会社Aと会社Bの関係は、
向きを持ったものですか持っていないものですか?
A→B と B→Aとでは意味が相当異なりますか?

上で"テキストベース"でいうのは、例えばこんなことです。
 
(1)企業Aを対象企業とし、それが直接関係する企業をリストアップする(関連度1)
(2)関連度1の企業が直接関係(Aからは間接的に関係)する企業をリストアップする(関連度2)
(3)以下、必要に応じて関連度n までの関係企業をリストアップする。
 
まずはこうした作業を行って対象企業を絞り込む必要があるでしょう。
それができてから、必要なレベルでの企業を対象に相関図を書く(関連度に応じて色をつける)
といったシナリオになるんでしょう。
 
使い勝手の良い、気の利いたものを作ろうとすれば、
こうした質問掲示板でどうにかなるものでもないので、
会社と相談して、しかるべきステップを踏むほうがよいのではないですか?
メンテナンスとか、バグ対応とかが必要になるはずですから。

(γ) 2020/08/19(水) 23:14


(γ) 様
早速のコメントありがとうございます。

きごう会社Aと会社Bの関係は、 向きを持ったものですか持っていないものですか? A→B と B→Aとでは意味が相当異なりますか? もちろん向きを持っています。まさに過去ログと同じ題材でした。
メーカー→一次商社→二次…n次→エンドユーザという向きです。
また、相関図にしたいデータは表形式で準備済みです。
ただ、向きや見た目など完璧は求めておらず「繋がり=視覚的に分かりやすい相関図」を
考えたため、列は2列のシンプルなデータを取り込まれれば思ってました。

使い勝手の良い、気の利いたものを作ろうとすれば、 こうした質問掲示板でどうにかなるものでもないので、 会社と相談して、しかるべきステップを踏むほうがよいのではないですか? メンテナンスとか、バグ対応とかが必要になるはずですから。 会社として取り組んではおらず、私個人の困りごとのため、
メンテは個人でやろうかと考えています。
※弊社のシステム部に相談して半年後の今、出来ないと回答があったので
 皆様のお知恵をご教授頂ければと思った次第です。

掲示板での質問は時期早々と指摘いただいたばかりで申し訳ありませんが、
wingraphvisのダウンロード方法がわかりません。
過去ログやその他ネット記事参照しましたが、ダウンロードサイトが当時と変わっているためか
手順通りに出来ない箇所があり…。教えていただけないでしょうか。

(ふなはし) 2020/08/20(木) 00:12


(γ) 様
上記が見にくい文章になったしまったので再投稿します。

(ご指摘)
 会社Aと会社Bの関係は、 向きを持ったものですか持っていないものですか?
A→B と B→Aとでは意味が相当異なりますか?
(回答)
 向きを持っています。まさに過去ログと同じ題材でした。
メーカー→一次商社→二次…n次→エンドユーザという向きです。
また、相関図にしたいデータは表形式で準備済みです。
ただ、向きや見た目など完璧は求めておらず「繋がり=視覚的に分かりやすい相関図」を
考えたため、向きの考慮は不要です。
2列のシンプルなデータを取り込まれれば思ってました。

(ご指摘)
 使い勝手の良い、気の利いたものを作ろうとすれば、
こうした質問掲示板でどうにかなるものでもないので、
会社と相談して、しかるべきステップを踏むほうがよいのではないですか?
メンテナンスとか、バグ対応とかが必要になるはずですから。
(回答)
 会社として取り組んではおらず、私個人の困りごとのため、
メンテは個人でやろうかと考えています。
※弊社のシステム部に相談して半年後の今、出来ないと回答があったので 皆様のお知恵をご教授頂ければと思った次第です。

掲示板での質問は時期早々と指摘いただいたばかりで申し訳ありませんが、
wingraphvisのダウンロード方法がわかりません。
過去ログやその他ネット記事参照しましたが、ダウンロードサイトが当時と変わっているためか
手順通りに出来ない箇所があり…。教えていただけないでしょうか。
(ふなはし) 2020/08/20(木) 00:19


(γ)様

何度も申し訳ございません。

》視覚化というよりも、テキストベースで考える方が先でしょう。
》一足飛びにグラフ化したところで、検索が容易にできるというものでもないでしょう。
おっしゃる通りでした。
なので、下記サイトの手順14のハードコピーのような図が作れればと
思っております。

https://www.kkaneko.jp/tools/win/graphviz.html

Excel取り込みは諦め、dotファイルに会社の関係性を書き、
出力したpngやPDFをOCR(pngファイルにテキスト埋め込み)し、
テキスト検索しようと思います。

Graphvisのインストール方法をご教授頂けますと幸いです。

(ふなはし) 2020/08/20(木) 00:37


 ■本体のインストーラ
 https://www.kkaneko.jp/tools/win/graphviz.html
 で紹介されているのは、GraphViz本体です。
 ダウンロードのリンクを辿って
 Index of /Packages/stable/windows/10/msbuild/Release/Win32
 にあるgraphviz-2.38-win32.msi、
 つまり、
 https://www2.graphviz.org/Packages/stable/windows/10/msbuild/Release/Win32/graphviz-2.38-win32.msi
 が本体のインストーラです。
 ■
 私が利用したのは、WinGraphVizというDLLであって、それとは別です。
 WinGraphVizは、VBAなどから参照設定して使う用途のものです。

 ダウンロードの方法は、昔からどちらも変わってはいないはずです。

 本体のダウンロードページにもWinGraphvizへのリンクがあり、
 WinGraphviz* Win32/COM object (dot/neato library for Visual Basic and ASP).
 と紹介されています。

 念のため、WinGraphvizのインストール方法をメモしておきます。
 (1)
 http://wingraphviz.sourceforge.net/wingraphviz/
 を開くと、右上方向に
 Latest release
 WinGraphviz ver 1.0.2.25s
 というのが見えるので、それをクリック。

 (2)
 中央あたりに、
 Download binary files :
 が見える。
 その
 Binary File:WinGraphviz_v1.02.24.msi
 をクリックすると、ダウンロードできます。

 (3)
 explorer上で、それをダブルクリックすると、インストールが実行される。
 (発行元に関する確認のための警告(一般的なもの)などが表示されるが、
   問題ないので、OKを押す。)

 (4)インストール先のフォルダ(*)に、
 WinGraphviz.dll
 があることを確認する。((*)デフォルトのフォルダでも、別に指定したフォルダでも可)

 ■WinGraphvizの参照設定
 VBEの ツール ー 参照設定の 参照 をクリックして、
 上記(4)のファイルを指定する。
 すると、
 選択肢に
 Wingraphviz 1.01.7 Type Library
 が表示されるので、チェックを入れる。

 =========
 私はさきほど再実行して動作することを確認しました。
 初回の際は、上記と表示が少し異なる部分があるかも知れないが、
 そこは常識を働かせていただきたい。
 なお、ダウンロードのページにinstall方法、uninstall方法が書かれています。

 ■PDF化について。
 (1)
 WinGraphvizはかなり昔に開発されたものなので、PDFへ保存するというメソッドはないですね。
 (2)
 Graphviz本体であれば、引用された金子研究室のページにも記載がありますが、
 DOTという拡張子のファイル(DOT言語に沿ったテキストファイル)を作って、
 dot -T pdf d:\hoge.dot d:\hoge.pdf
 のように、dot.exeファイルを実行することになりますね。
(γ) 2020/08/20(木) 09:59

 訂正と若干の追記をしておきます。
 (1)
 訂正:
 |  dot -T pdf d:\hoge.dot d:\hoge.pdf
 |  のように、dot.exeファイルを実行することになりますね。
 未確認で引用してしまいました。
 私の環境 (dot -V では、dot - graphviz version 2.36.0 (20140111.2315)となっています)
 では、上記ではエラーになりました。

 https://graphviz.org/pdf/dotguide.pdf
 によると、
 | By default, dot operates in filter mode, reading a graph from stdin, and writing
 | the graph on stdout in the DOT format with layout attributes appended.
 となっているので、基本通り、リダイレクトを使って、
 dot -T pdf <test.dot >kekka.pdf
 とすると成功しました。

 outputファイルを指定する -oオプションを使って、
 dot -T pdf test.dot -okekka.pdf
 でもいいようです。

 (ちなみに、本体のDocumentationページの記事の新鮮度合いは、
   On-line reference pages  が最新で、
   userguide( https://graphviz.org/pdf/dotguide.pdf)は若干古いようです。
   ただし、包括的に知りたいのであれば、このUserGuideが最適でしょう。)

 (2)作成されたPDFは何もしなくても、日本語を含む文字検索ができました。
   (私にはちょっと意外でした)

 (3)dotコマンドを実行したときに、フォントに関する警告が出ます。
 |  couldn't load font "MS ゴシック Not-Rotated 14", falling back to "Sans Not-Rotated 14", expect ugly output.
 別に uglyにはなっていないですけどね。

 もしそれが気になるなら、元のdotファイルのフォント指定を
 IPAexGothicにでも指定してください。警告が出なくなります。
 (先日、matplotlibでグラフに日本語が使えない問題を経験し、その時の対応策にならって
   IPAexGothicを使ってみました。↓を参照ください。
 https://qiita.com/ldap2017/items/f014f1c22de269012273 
 )
(γ) 2020/08/20(木) 18:47

(γ)様
詳細にご教授頂きありがとうございます。
拡張子が.cabのものをインストールしてよく分からなくなっていたようです。
帰宅したらすぐやってみようと思います!
取り急ぎお礼申し上げます。
(ふなはし) 2020/08/20(木) 20:24

(γ)様

VBA実行時にエラーが出てしまい再度ご教授ください。

WinGraphvisをダウンロードし、2020/08/19(水) 11:39にコメント頂いたソースを引用し実行するとJPEGの生成の下記ソースでエラーになります。
>>Set img = dot.ToJPEG(strCMD)
エラー内容は、「システムエラーです。起動されたオブジェクトはクライアントから切断されました。」です。

WinGraphvisはデスクトップにおいてあり、その中に.dllファイルはありVBAの参照設定もしました。
原因分かりますでしょうか。

宜しくお願い致します。
(ふなはし) 2020/08/21(金) 22:58


いつもはWin7,Excel2010を使用していますが、
別マシン(Win10,Excel2019)でも確認しましたが、
いずれの環境でも正常動作しました。

参照設定する際に、「参照」ボタンを利用すると書きましたが、
何もしなくても、インストールが成功していれば、選択肢に
WinGraphviz 1.01.7 Type Library
が表示されるようです。
これにチェックを入れることで参照設定が可能になります。
(訂正しておきます。)

申し訳ないですが、そのエラーメッセージでは私にはわかりません。
画像ファイルの作成は、いったんコメントアウト(無効)にして、
text = dot.ToPlain(strCMD)
が動作するかどうか確認して下さい。

それでも動作しないなら、いったんExcelを閉じ、
WinGraphVizをアンインストールして、再度、インストールしてみる、
くらいしか思いつきません。
そのエラーは、システム内部の状況を示しただけであり、
ユーザーが何かアクションを起こせる、といったレベルのものではないと思います。

(γ) 2020/08/21(金) 23:36


mainプロシージャの最後に、
Set dot = Nothing
を入れてみるというトライもお願いします。

(γ) 2020/08/21(金) 23:39


(γ様)
もう一点ご教授下さい。

2020/08/20(木) 09:59にコメント頂いた下記について
》(2)
》 Graphviz本体であれば、引用された金子研究室のページにも記載がありますが、
》 DOTという拡張子のファイル(DOT言語に沿ったテキストファイル)を作って、
》 dot -T pdf d:\hoge.dot d:\hoge.pdf
》 のように、dot.exeファイルを実行することになりますね。

本体もインストールし、test.dotファイルをデスクトップに作り、
コマンドプロンプトを開いた直後にカーソル当たっているところに
dot -T pdf デスクトップのパス\test.dot デスクトップのパスtest.pdf
と入力してエンター押すと「dotは内部コマンドまたは外部コマンド、操作可能なプログラムとして認識されていません」とでます。
初歩的な質問で申し訳ありませんが、コマンドプロンプトでどのようにdotコマンドを実行するのでしょうか。

(ふなはし) 2020/08/21(金) 23:41


γ様

投稿が前後してしまいすみません。

》参照設定する際に、「参照」ボタンを利用すると書きましたが、
》何もしなくても、インストールが成功していれば、選択肢に
》WinGraphviz 1.01.7 Type Library
》が表示されるようです。
》これにチェックを入れることで参照設定が可能になります。
上記挙動になっています。

ご指摘いただいた内容でトライしてみます。

(ふなはし) 2020/08/21(金) 23:45


もう一点、確認ですが、データの量はどの程度でしょうか。
WinGraphviz側でエラーが発生しているのかもしれませんね。
少量データでやっても同じですか?

(γ) 2020/08/21(金) 23:49


データ量は4行です。
下記2点試しました。
Set dot = Nothingを入れる、また
jpegの箇所をコメントアウトしてデバックしましたが、
次はdot.ToPlain〜の箇所で同様のエラーとなりました。
変数dotに対してクリエイトオブジェクトしているところに原因、すなわにインストールが正常に出来ていなさそうです。
アンインストールしてトライします。
(ふなはし) 2020/08/21(金) 23:57

γ様

連続投稿、大変失礼いたします…。
今までwin10,excel2010でやっており、アンインストールも出来ない(=ドライバーのRemove wingraphvisをしても
処理が20分経っても進まない)です。
その為、Repare wingraphvisをして見ましたが、結果は変わりませんでした。
また、別のPCのwin7で試しましま。権限の問題でcドライブでは無く、Dドライブにdllファイルをインストールし、
vbaの参照設定し、マクロ実行するとエラー「このコンポーネントの
ライセンス情報が見つかりません。デザイン環境でこの機能を使うために必要なライセンスがありません」となります。

やはりインストールが正常に出来ていない模様です。
初心者が陥りやすい見落としているポイントなど無いでしょうか?
何度も何度も恐れ入りますがご教授下さい。
(ふなはし) 2020/08/22(土) 00:36


 | なお、ダウンロードのページにinstall方法、uninstall方法が書かれています。
 と書きましたが、
 紹介した、wingraphvizのインストールページ
 http://wingraphviz.sourceforge.net/wingraphviz/
 に、書かれています。

 | Uninstall (WinGraphviz_v1.xx.x.msi)
 | 1.Uninstall from control panel
 | 2.Complete
 とされています。
 コントロールパネルの
 プログラムと機能
 でWinGraphvizをアンインストールできると思いますが。

(γ) 2020/08/22(土) 06:46


γ様

WinGraphvizをアンインストールして見ましたが同様の結果でした。
色々調べてみます。ありがとうございます。
(ふなはし) 2020/08/22(土) 13:30


γ様、及び皆様

エラー解決しませんが、一度下記の方法を試したくご教授下さい。

■試したいこと
CreateObject関数でwingraphvisを生成するのではなく、newで書く方法。
下記サイトで治った事例あったためです。
https://teratail.com/questions/25931

■エラー内容
実行時エラー 2147417848(80010108)
オートメーションエラーです。
起動されたオブジェクトはクライアントから切断されました。

また、
・参照設定が不可になっていないことを確認
・wingraphvisのインストール先のパスが環境変数に設定されていること確認

宜しくお願い致します。
(ふなはし) 2020/08/22(土) 17:08


 そうですか残念ですね。こちらは開発元でもないので、基本的にはわかりません。
 こちらでは再現できないエラーということもあります。

 (1)
 恐縮ですが、下記の確認をしてもらえませんか?

 cabタイプのものも操作されたとのことですので、念のため、
 ↓こちらのアンインストール方法も実行して、
 再インストール(msiファイルで)してもらえますか?
 特に4.を忘れずにいったん削除してみてください。
 3.は後半のほうかと思います。

 Uninstall (WinGraphviz_v1.xx.x.cab)
 1.Open a Command Window
 2.Goto the system dicroty "\[Windows]\SYSTEM32"
 3.if your windows is Win98/me then run "regserver.exe WinGraphviz.dll /u" 
   to unregist it on your  system
   if your windows is WinNT/2000/XP then run "regsvr32.exe WinGraphviz.dll /u" 
   to unregist it on your system
 4.Delete WinGraphviz.dll

 (2)
 データに依存している可能性もあり、こちらでも確認したいので、
     strCMD = strCMD & "}"
     '''Debug.Print strCMD
 のコメントをはずして、
 イミディエイトウインドウに出力されたものを、こちらに書いてもらえますか?    

(γ) 2020/08/22(土) 23:08


γ様

(1)
cabを削除し、msiを再インストールしました。
VBA画面の▶実行すると、下記エラーが出ました。
「ToJPEGメソッドは失敗しました:‘IDOT’オブジェクト」
EXCELの図形に上記マクロを登録して押下すると、下記エラーが出ます。
「実行時エラー 2147417848(80010108)
オートメーションエラーです。
起動されたオブジェクトはクライアントから切断されました。」

(2)
シート1に下記データを入力した結果です。

A C
A D
B D

以下、デバック出力した結果です。

digraph G {charset="UTF-8";

 n1 -> n2 [ dir=forward ] ; 
 n1 -> n3 [ dir=forward ] ; 
 n4 -> n3 [ dir=forward ] ; 
 n1 [shape = "box" , height=.25 , label="A" , fontname="MS ゴシック"]  
 n2 [shape = "box" , height=.25 , label="C" , fontname="MS ゴシック"]  
 n3 [shape = "box" , height=.25 , label="D" , fontname="MS ゴシック"]  
 n4 [shape = "box" , height=.25 , label="B" , fontname="MS ゴシック"]  
}

宜しくお願い致します。
(ふなはし) 2020/08/23(日) 00:08


コメント拝見。
(1)
>cabを削除し、msiを再インストールしました。
"regsvr32.exe WinGraphviz.dll /u" も実行されていますね?
何かメッセージ等出ましたか?

dot文字列は正常に作成されているようです。

(2)
WinGraphvizがダメなら、Graphviz本体を使いましょう。
インストールしておいてもらえますか?

(γ) 2020/08/23(日) 11:00


γ様

(1)
"regsvr32.exe WinGraphviz.dll /u"を実行したところ、
指定されたモジュールが見つかりません。とメッセージ出ました。
その為、"\[Windows]\SYSTEM32"にあるGraphvizフォルダのdllファイルを物理削除し、Graphvizフォルダ自体も物理削除しました。

(2)
Graphviz本体をインストールしました。

(ふなはし) 2020/08/21(金) 23:41のコメントで下記を質問しておりました。

》》2020/08/20(木) 09:59にコメント頂いた下記について
》》(2)
》》 Graphviz本体であれば、引用された金子研究室のページにも記載がありますが、
》》 DOTという拡張子のファイル(DOT言語に沿ったテキストファイル)を作って、
》》 dot -T pdf d:\hoge.dot d:\hoge.pdf
》》 のように、dot.exeファイルを実行することになりますね。
》本体もインストールし、test.dotファイルをデスクトップに作り、
》コマンドプロンプトを開いた直後にカーソル当たっているところに
》dot -T pdf デスクトップのパス\test.dot デスクトップのパスtest.pdf
》と入力してエンター押すと「dotは内部コマンドまたは外部コマンド、操作可能なプログラムと
》して認識されていません」とでます。
》初歩的な質問で申し訳ありませんが、コマンドプロンプトでどのように
》dotコマンドを実行するのでしょうか。

C:\Program Files (x86)\Graphviz2.38\bin にインストールされたdot.exeを起動し、
「dot -V」と入力しエンターキーを押下すると、下記メッセージが出ます。
どのようにdotコマンドを実行するのでしょうか。

Error:<stdin>: syntax error in line 1 near 'dot'

何度も何度も大変申し訳ございません。
ご教示ください。

(ふなはし) 2020/08/23(日) 12:30


Graphviz でつまづいて時間を浪費するくらいなら SOH さんのを参考に作成したらどうです。

(FUNA) 2020/08/23(日) 13:15


 "regsvr32.exe WinGraphviz.dll /u"
 はレジストリへの登録情報を解除するものと理解していますので、
 すでにコンパネで正確に削除されているのか、
 不具合が残っているのか不明ですね。
 とりあえず放置しておきましょう。

 あらためて、本体を使うバージョンを書いて見ました。
 ■を付けた2カ所だけ、必要に応じて修正してください。

 === 参考コード =========
 Option Explicit

 ' Graphviz を使った企業関連図の作成
 '    【■環境設定】
 '     Graphviz が必要です。(Open Sourceです)
 '     https://graphviz.org/about/
 ' Sheet1のA列、B列にあるデータをもとに、
 ' 企業関連図(pdf,jpgファイル)を作成します。
 '
 Const exefile = """D:\Mytool\graphviz\bin\dot.exe"""  '''■■ ここは要修正。※バグ修正しました。
                                                   ''' Pathを通しておけば単に"dot.exe"で良い
 Dim wsData As Worksheet
 Dim mat
 Dim dic As Object

 Sub main()
     Dim rng As Range
     Dim strCMD As String

     Set wsData = Worksheets("Sheet1")   ''■ 元データがあるシートを指定

     '対象とするデータ
     Set rng = wsData.Cells(1, 1).CurrentRegion.Resize(, 2) 'そのA列B列にデータがあるものとした

     '(1)Sheet1のデータを元に、企業名を"n1","n2",...の連番に変換(dotファイル作成の都合上)
     Call dataConvert(rng)

     '(2) DOT言語のための文字列strCMDを作成 ---------------------------
     strCMD = makeDOTstrings()

     '(3) dotファイルをカレントフォルダにUTF-8で書き出す(ファイル名は"tmp.dot"に固定)
     Call fsave(strCMD)

     '(4) PDFファイルを作成
     Call make_outputfile("pdf", "output.PDF")

     '(5) jpgファイルを作成
     Call make_outputfile("jpg", "output.jpg")

 End Sub

 Private Sub dataConvert(rng As Range)
     'GraphvizのDOT言語におけるnode名が日本語対応していないようなので、
     'いったんn1,n2,n3・・・といった仮node名に読み替える作業を行う。
     Dim k As Long
     Dim e
     Set dic = CreateObject("Scripting.Dictionary")
     mat = rng.Value

     ' dic  key:元の企業名    item:"n1","n2",...の連番
     For Each e In mat
         If Not dic.exists(e) Then
             k = k + 1
             dic(e) = "n" & k
         End If
     Next
 End Sub

 Function makeDOTstrings() As String

     Dim strCMD As String
     Dim k As Long
     Dim s1 As String, s2 As String
     Dim key

     strCMD = "digraph G {charset=""UTF-8"";   " & vbCrLf

     'Edgeの指定
     For k = 1 To UBound(mat)
         s1 = mat(k, 1)         ' 企業1
         s2 = mat(k, 2)         ' 企業2
         strCMD = strCMD & " " _
                & dic(s1) & " -> " & dic(s2) & " ;" & vbCrLf
     Next

     'nodeの指定
     For Each key In dic
         'key:元の名称      item:変換後(n1,n2 ....)
         strCMD = strCMD & " " & dic(key) _
            & " [shape = ""box"" , height=.25 , label=""" & key & """" _
            & " , fontname = ""MS ゴシック""] " & vbCrLf
     Next

     strCMD = strCMD & "}"
     '''Debug.Print strCMD
     makeDOTstrings = strCMD
 End Function

 'UTF-8でファイル保存
 Function fsave(s As String)
     Const adTypeBinary = 1
     Const adTypeText = 2
     Const adSaveCreateOverWrite = 2
     Const fname As String = "tmp.dot"

     With CreateObject("ADODB.Stream")
         .Type = adTypeText
         .Charset = "UTF-8"
         .Open
         .writetext s

         'BOMなしにして保存
         .Position = 0               'ストリームの位置を0にする
         .Type = adTypeBinary
         .Position = 3               'ストリームの位置を3にする
         Dim byteData() As Byte      '一時格納用
         byteData = .Read
         .Close

         .Open
         .write byteData
         .savetofile fname, adSaveCreateOverWrite
         .Close
     End With
 End Function

 Function make_outputfile(format As String, file As String)
     Const fname As String = "tmp.dot"
     Dim sCMD As String

     sCMD = exefile & " -T " & format & " """ & fname & """ " & " -o " & """" & file & """"
     ' パス名にspaceを含む時に耐えられるよう、ダブルクォーテーションで囲む

     'WSHで sCMDを実行
     With CreateObject("Wscript.Shell")
          .Run sCMD, 7, True   '' ※バグ修正済み
     End With
 End Function

(γ) 2020/08/23(日) 13:46


 細かくは触れませんが、
 | "regsvr32.exe WinGraphviz.dll /u"を実行したところ、
 | 指定されたモジュールが見つかりません。とメッセージ出ました。
 | その為、"\[Windows]\SYSTEM32"にあるGraphvizフォルダのdllファイルを物理削除し、Graphvizフォルダ自体も物理削除しました。

 WinGraphvizは 本体のGraphvizとはまったく独立したものということを理解して下さい。

 | C:\Program Files (x86)\Graphviz2.38\bin にインストールされたdot.exeを起動し、
 | 「dot -V」と入力しエンターキーを押下すると、下記メッセージが出ます。
 | どのようにdotコマンドを実行するのでしょうか。
 | Error:<stdin>: syntax error in line 1 near 'dot'
 dot.exeの用法はきちんと決められています。
 ExcelやWordと違って、何らかのWindowが表示されるものではありません。
 コマンドライン形式のものです。

 入力ファイルなどの引数を与えずにdotを実行すると、
 標準入力を入力とすることから、入力待ちの状態になり、
 次に与えられたものをDOT文字列と解釈します。
 "dot -V" という文字列を継続入力すれば、
 それをDOT文字列と解釈してしまうわけです。
 で、それはアカンな、と回答が返ってくるのは自然です。

 2020/08/20(木) 18:47でも若干触れましたが、
 dot -T pdf test.dot -o kekka.pdf
 とかいった書き方です。
 ユーザーガイドや、日本語の解説文書などを探して、概略を知る必要はあるでしょう。

 なお、dotファイルは、BOMなしの文字コードUTF-8のテキストファイルである必要があります。
 私の先ほどのコードの中ではそうした対応をしていますが、
 手作業でするときには、注意が必要です。

 いずれにしてもこうした検証作業ないしメンテナンス(機能アップ)等が発生するので、
 業務上の必要性から行うことなら、会社のしかるべきところと連携して、
 そのサポートを受けるべきですね。

 なお、提示したコードが動作するまでは成り行き上コメントさせて頂きますが、
 それ以上のリクエストにはお答えする積もりはありませんので、
 上記の点を念頭に置いて頂ければと思います。予めご了承願います。

(γ) 2020/08/23(日) 14:59


(FUNA)様
ご指摘ありがとうございます。
SHO様が紹介して頂いた方法だと約500社以上を管理するのが手間かつキーワード検索できないので断念しました。

(γ)様
本体を使うコードをVBAに記載して実行しました。
どこにPDF、jpgファイルが出力されるのでしょうか。
実行時、特にメッセージ等は表示されず何も起きませんでした。
下記がmake_outputfileメソッドの変数sCMDのデバック結果です。

C:\Program Files (x86)\Graphviz2.38\bin\dot.exe -T pdf "tmp.dot" -o "output.PDF"
C:\Program Files (x86)\Graphviz2.38\bin\dot.exe -T jpg "tmp.dot" -o "output.jpg"

また、総括コメント頂いたように業務で使うのであればγ様のおっしゃる通りです。
上記のGraphviz本体の方で出力結果を確認することが出来ましたら後はこちらで頑張りますので
退散いたします。何度も申し訳ございませんがご教授ください。
(ふなはし) 2020/08/23(日) 20:01


カレントフォルダに書き出している積もりですが、
exeファイルのパスにスペースが入っていることが影響していると思われます。
Const exefile = """C:\Program Files (x86)\Graphviz2.38\bin\dot.exe"""
と変更したらどうなりますか?

(γ) 2020/08/23(日) 20:25


うーん、ちょっとうまくいかないですね。
私の手元では無論動作しているのですが、
スペースが悪さをしてしまうようです。
(γ) 2020/08/23(日) 20:40

 >管理するのが手間かつキーワード検索できないので
 Graphviz で手間が省略かつキーワード検索できるんですか。
 約500社以上とありますがすべて関連性があるんですか。
(FUNA) 2020/08/23(日) 20:44

 2020/08/23(日) 20:25の修正に加えて、
    With CreateObject("Wscript.Shell")
         .Run sCMD, 7, True
    End With
 と変更してみてください。
 たぶんこれでカレントフォルダにPDF,JPGが出力されるはずです。
 確認漏れでしたね。
(γ) 2020/08/23(日) 20:45

■(FUNA)様
》 >管理するのが手間かつキーワード検索できないので
》 Graphviz で手間が省略かつキーワード検索できるんですか。
》 約500社以上とありますがすべて関連性があるんですか。
 Graphvizで手間が省略できる理由としましては、Excelで図と矢印で見栄えを気にしつつ手作業で作らなくても、親子関係を階層を考慮せずに2列に書き並べたデータをGraphvizに取り込むだけで、PDF出力できるため相関図の作成の手間が省略されると考え皆様のお知恵を拝借させていただきました!
 また、キーワード検索につきましては、出力結果のPDFはテキスト埋め込まれており、キーワード検索が可能です。電話で問合せ受けた際に、キーワード検索することで、どんな商流で今後相見積もりの依頼があるかなどの想定が瞬時に判断でき、見積金額の判断に大いに役立つと考えています。
 約500社以上はすべて関連性(商流)があります。メーカー→1次商社→2次商社→・・・n次商社→サブコン→ゼネコン→エンドユーザーのようなイメージです。また1次商社と3次商社は直接取引があり、2次商社を介さずに親子関係があったりと、かなり複雑です。
色々と記載しましたが、FUNA様のおっしゃるようにGraphvizのインストールで躓いているようでは…とのご指摘もごもっともです。今後勉強して補完します。

■(γ)様
PDF及びPNG出力出来ました…(:_;)!!
何度もご丁寧にご教授いただき本当にありがとうございます。
また、階層分かれており見た目も非常にきれいです(考慮してコード作成して頂いたんですかね⁉)。
さらに使いやすくなるように勉強します。ありがとうございます。
(ふなはし) 2020/08/24(月) 21:39


 とりあえず形になったようで、よかったです。
 >また、階層分かれており見た目も非常にきれいです(考慮してコード作成して頂いたんですかね⁉)。
 そうですか、私は特段の配慮はしていませんが。

 あとは、もし必要なら2020/08/19(水) 23:14に書いた点などを
 しかるべきサポートのもとで検討されたらどうでしょうか。

 なお、将来、閲覧する方のために、2020/08/23(日) 13:46のコードについて、
 後刻判明した不具合の修正をしておくつもりです。

 【以下、私的メモ】
 私もいくつか改めて確認できたところがありました。
 ・UTF-8(BOMなし)のファイル保存方法
 ・spaceありパス名を使った、外部コマンドの実行方法
 など。

 また、dot.ToPlain(strCMD)の結果を使ってシート上に図形を書き込む話に関して、
 arrowheadをつけるのとつけないので、書き出される線のhead部分の座標が異なります。
 これは、数年前には私には原因不明でしたが、以下の気づきがありました。
 (矢印ありのときは、先頭の矢印あり部分が欠落して、その結果、nodeとの接続部分に
   空きが発生するんでしょうね。これは、仕様とも不具合とも両面の見方がありますが、
   いずれにせよ、末端ユーザーではどうにもなりません。)

(γ) 2020/08/24(月) 22:05


γ様

列が150個以上並び横に広がると、キーワード検索は出来ますが
PDFの見た目は真っ白になってしまいました。
あまりに横伸びするとNGなようです。
2020/08/19(水) 23:14に頂いたコメントのように、どの企業に
焦点を絞るかなど、精査して活用できればと思います。

色々とご教授頂きましてありがとうございました。
(ふなはし) 2020/08/24(月) 22:55


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.