#はじめに
弊社の汎用機及びそれに群がるシステムでは、オンライン処理、バッチ処理が毎日動作しており、大、中、小合わせるとおよそ100種類以上の規模になります。その個々の事務はファイルの作成、更新、参照を繰り返して事務を進めるのですが、個々の事務は必ずしも独立していません。更に、全体を俯瞰する資料が存在しないため、システムの全体見直しを行う際に非常に困ります。
#全体システムの見える化
今回、保守・業務担当にお願いし、各業務ごとに参照しているファイルのうち自業務のファイルではないものについてまとめてもらい、その情報の分析を networkx を用いて有効グラフ化した。なお,見直しにあたり,集約結果から各事務どうしの結合度を求めた。原則、アルファベット1文字が業務を表し、もう1文字を合わせたアルファベット2文字で業務にぶら下がる事務を表している。
#作業の流れ
- 全事務のオンライン、バッチシステムの参照関係
- 方法:人力(機械化も可能だが,今回は業務担当にお願いした)
- 入力:業務知見
- 出力:参照関係ファイル
- オンライン、バッチ業務の参照関係を記した各々1ファイル(参照関係ファイル)にまとめた。
- 方法:プログラム
- 入力:参照関係ファイル
- 出力:参照関係(集約前)結果リスト
- 今回の業務見直しで 2 が集約されるため、その見直し結果として集約関係ファイルを作成した
- 方法:人力
- 入力:業務見直し方針
- 出力:集約関係ファイル
- 3の集約関係ファイルを参照し、1で作成した参照関係(集約前)結果リストを再度まとめなおした
- 方法:プログラム
- 入力:参照関係ファイル
- 出力:参照関係(集約後)結果リスト
- 4 で作成したファイルをもとにnetworkxの有効グラフで結んだ
- 方法:プログラム
- 入力:参照関係結果ファイル
- 出力:参照結果グラフ
#材料
コーディングルール等は一切無視しているので、決して参考にしないでください。笑
excel1 = new ActiveXObject("Excel.Application");
excelFile3 = "C:\\work\\analyzeInternal\\all.csv";//オンライン参照関係結果リスト
excel3 = new ActiveXObject("Excel.Application");
excel3.Workbooks.Open(excelFile3, false, false);
dstBook3 = excel3.Workbooks(excel3.Workbooks.Count);
excelFile4 = "C:\\work\\analyzeInternal\\allb.csv";//バッチ参照関係結果リスト
excel4 = new ActiveXObject("Excel.Application");
excel4.Workbooks.Open(excelFile4, false, false);
dstBook4 = excel4.Workbooks(excel4.Workbooks.Count);
excel1 = new ActiveXObject("Excel.Application");
Path = "C:\\work\\analyzeInternal";
createReferenceList(Path);
function createReferenceList(target)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var folders = fso.GetFolder(target);
var e = new Enumerator(folders.files);
var g = new Enumerator(folders.SubFolders);
if((e.item() == null) && (g.item() == null)) return [];
if(e.item() != null)
{
for(; !e.atEnd(); e.moveNext())
{
if(e.item().name.match(/[^(all)].xlsx$/i))
{
WScript.Echo(e.item().name);
excel1.Workbooks.Open(e.item(), false, false);
srcBook1 = excel1.Workbooks(excel1.Workbooks.Count);
var gyoumu = srcBook1.WorkSheets(1).Cells(3,4).Value;
WScript.Echo("オンライン:" + gyoumu);
for(var i = 7; i < 100; i++)
{
var jimur = srcBook1.WorkSheets(1).Cells(i,3).Value;
var jimuc = srcBook1.WorkSheets(1).Cells(i,4).Value;
if((undefined != jimuc) && (undefined != jimur))
{
WScript.Echo(jimur);
WScript.Echo(jimuc);
var row = dstBook3.WorkSheets(1).Range("A2:A104").find(jimur).Row;
var column = dstBook3.WorkSheets(1).Range("B1:DP1").find(jimuc).Column;
dstBook3.WorkSheets(1).Cells(row,column).Value = 1.0;
}
else
{
break;
}
}
var gyoumu = srcBook1.WorkSheets(2).Cells(3,4).Value;
WScript.Echo("バッチ:" + gyoumu);
for(var i = 7; i < 100; i++)
{
var jimur = srcBook1.WorkSheets(2).Cells(i,3).Value;
var jimuc = srcBook1.WorkSheets(2).Cells(i,4).Value;
if((undefined != jimuc) && (undefined != jimur))
{
WScript.Echo(jimur);
WScript.Echo(jimuc);
var row = dstBook4.WorkSheets(1).Range("A2:A104").find(jimur).Row;
var column = dstBook4.WorkSheets(1).Range("B1:DP1").find(jimuc).Column;
dstBook4.WorkSheets(1).Cells(row,column).Value = 1.0;
}
else
{
break;
}
}
excel1.DisplayAlerts = false;
excel1.Quit();
}
}
}
if(g.item() == null) return [];
for(; !g.atEnd(); g.moveNext())
{
//解析不要なフォルダを確認しない。
if(!g.item().name.match(/old|test|bk|temp|log/i))
{
var result = createReferenceList(g.item());
}
}
}
excel3.DisplayAlerts = false;
dstBook3.SaveAs(excelFile3);
excel3.Quit();
excel4.DisplayAlerts = false;
dstBook4.SaveAs(excelFile4);
excel4.Quit();
WScript.StdErr.WriteLine("start");
excel1 = new ActiveXObject("Excel.Application");
excelFile2 = "集約関係ファイル.csv";
excel2 = new ActiveXObject("Excel.Application");
excel2.Workbooks.Open(excelFile2, false, false);
srcBook2 = excel2.Workbooks(excel2.Workbooks.Count);
excelFile3 = "C:\\work\\analyzeInternal\\gyo.csv";
excel3 = new ActiveXObject("Excel.Application");
excel3.Workbooks.Open(excelFile3, false, false);
dstBook3 = excel3.Workbooks(excel3.Workbooks.Count);
excelFile4 = "C:\\work\\analyzeInternal\\gyob.csv";
excel4 = new ActiveXObject("Excel.Application");
excel4.Workbooks.Open(excelFile4, false, false);
dstBook4 = excel4.Workbooks(excel4.Workbooks.Count);
excel1 = new ActiveXObject("Excel.Application");
Path = "C:\\work\\analyzeInternal";
createReferenceList(Path);
function createReferenceList(target)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var folders = fso.GetFolder(target);
var e = new Enumerator(folders.files);
var g = new Enumerator(folders.SubFolders);
if((e.item() == null) && (g.item() == null)) return [];
if(e.item() != null)
{
for(; !e.atEnd(); e.moveNext())
{
if(e.item().name.match(/[^(all)].xlsx$/i))
{
WScript.Echo(e.item().name);
excel1.Workbooks.Open(e.item(), false, false);
srcBook1 = excel1.Workbooks(excel1.Workbooks.Count);
var gyoumu = srcBook1.WorkSheets(1).Cells(3,4).Value;
WScript.Echo("オンライン:" + gyoumu);
for(var i = 7; i < 100; i++)
{
var frow = 0;
var f2ro = 0;
if(undefined == srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(1).Cells(i,3).Value))
{
continue;
}
else
{
frow = srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(1).Cells(i,3).Value).Row;
}
if(undefined == srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(1).Cells(i,4).Value))
{
continue;
}
else
{
f2row = srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(1).Cells(i,4).Value).Row;
}
var jimur = srcBook2.WorkSheets(1).Cells(frow,2).Value;
var jimuc = srcBook2.WorkSheets(1).Cells(f2row,2).Value;
if((undefined != jimuc) && (undefined != jimur))
{
WScript.Echo(jimur);
WScript.Echo(jimuc);
var row = dstBook3.WorkSheets(1).Range("A2:A104").find(jimur).Row;
var column = dstBook3.WorkSheets(1).Range("B1:DP1").find(jimuc).Column;
if(row == column)
{
continue;
}
if(dstBook3.WorkSheets(1).Cells(row,column).Value == null)
{
dstBook3.WorkSheets(1).Cells(row,column).Value = 1;
}
else
{
dstBook3.WorkSheets(1).Cells(row,column).Value++;
}
}
else
{
break;
}
}
var gyoumu = srcBook1.WorkSheets(2).Cells(3,4).Value;
WScript.Echo("バッチ:" + gyoumu);
for(var i = 7; i < 100; i++)
{
var frow = 0;
var f2ro = 0;
if(undefined == srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(2).Cells(i,3).Value))
{
continue;
}
else
{
frow = srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(2).Cells(i,3).Value).Row;
}
if(undefined == srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(2).Cells(i,4).Value))
{
continue;
}
else
{
f2row = srcBook2.WorkSheets(1).Range("A2:A104").find(srcBook1.WorkSheets(2).Cells(i,4).Value).Row;
}
var jimur = srcBook2.WorkSheets(1).Cells(frow,2).Value;
var jimuc = srcBook2.WorkSheets(1).Cells(f2row,2).Value;
if((undefined != jimuc) && (undefined != jimur))
{
WScript.Echo(jimur);
WScript.Echo(jimuc);
var row = dstBook4.WorkSheets(1).Range("A2:A104").find(jimur).Row;
var column = dstBook4.WorkSheets(1).Range("B1:DP1").find(jimuc).Column;
if(row == column)
{
continue;
}
if(dstBook4.WorkSheets(1).Cells(row,column).Value == null)
{
dstBook4.WorkSheets(1).Cells(row,column).Value = 1;
}
else
{
dstBook4.WorkSheets(1).Cells(row,column).Value++;
}
}
else
{
break;
}
}
excel1.DisplayAlerts = false;
excel1.Quit();
}
}
}
if(g.item() == null) return [];
for(; !g.atEnd(); g.moveNext())
{
//解析不要なフォルダを確認しない。
if(!g.item().name.match(/old|test|bk|temp|log/i))
{
var result = createBatchFiles(g.item());
}
}
}
excel2.DisplayAlerts = false;
srcBook2.SaveAs(excelFile2);
excel2.Quit();
excel3.DisplayAlerts = false;
dstBook3.SaveAs(excelFile3);
excel3.Quit();
excel4.DisplayAlerts = false;
dstBook4.SaveAs(excelFile4);
excel4.Quit();
-
各セルに入った数値は,集約後の各事務どうしの結合度となる
-
グラフ化処理プログラム(2つのページ参考からコピペ:(ほぼ捜索時間)15分)
import pandas as pd
#バッチの場合
df_links = pd.read_csv('./gyob.csv')
import networkx as nx
import matplotlib.pyplot as plt
import re
import numpy as np
G = nx.DiGraph()
NUM = len(df_links.index)
print(NUM)
node_labels = ["TA","TE","TD","AA","CA","CC","GG","SS","BH","BN","IH","LA","WA","IU","MF","IT","IQ",
"KK","TC","KS","IF","JG","ZK","SJ","JJ","BK","HG","KT","KM"]
for i in range(0,NUM):
for j in range(1,NUM):
if df_links.iloc[i,j] >= 1.0:
print("---")
print("i:",i)
print(node_labels[i])
print("j:",j)
print(node_labels[j-1])
print(df_links.iloc[i,j])
print("---")
G.add_edge(node_labels[i],node_labels[j-1])
pos = {
#ノード数で分母を調整
n: (np.cos(2*i*np.pi/21), np.sin(2*i*np.pi/21))
for i, n in enumerate(G.nodes)
}
nx.draw_networkx(G,pos=pos,node_color="g",edge_color="g",font_color="w")
plt.show()
#結果
#参考
この2つのページがとても参考になりました。ありがとうございます。
分析ノート:NetworkXのグラフを可視化するときに頂点の座標を指定する
コピペで試せる!Pythonのnetworkxでかっこいいネットワーク図を描いてみよう