ラベル #社内DX案件紹介 の投稿を表示しています。 すべての投稿を表示
ラベル #社内DX案件紹介 の投稿を表示しています。 すべての投稿を表示

2023年3月2日木曜日

【社内DX案件紹介】値の入っているシートのみ印刷する

 ■社内DXの依頼内容

ブックの中でB1セル以下に値があるシートのみを印刷したい


■社内DXの条件

・1シート目は印刷対象外としたい

・2シート目以降でB1セル以降に値があるシートを印刷したい

・印刷するシートはマクロが入っているブック内にある


■諸元

・2シート目から全シートを周回する

・B2セル以降に値があれば配列にシート名を格納する

・シート名が入った配列を対象として印刷プレビューする


■作成方法

1.2シート目からデータのあるファイルを準備する。

2シート目4シート目6シート目に値があるブック

2.実際にマクロを書いていく

Sub Sample()

Dim st() As String  '/--シート名を格納する配列--/'
Dim i As Integer    '/--シート周回カウンタ--/'
Dim m As Integer    '/--最大シート数--/'
Dim c As Integer    '/--配列用カウンタ--/'
Dim y As Long       '/--行数を格納--/'

'/--全シート数を入れる--/'
m = Worksheets.Count

'/--配列は0スタートなので+1したときに0になるようカウンタは-1からスタート--/'
c = -1
For i = 2 To m
    y = Sheets(i).Cells(Rows.Count, 2).End(xlUp).Row
    If y > 1 Then
        c = c + 1
        ReDim Preserve st(c)
        '/--シート名を配列に格納する--/'
        st(c) = Sheets(i).Name
    End If
Next i

'/--配列に格納したシート名のみを印刷プレビューする--/'
Sheets(st).PrintPreview


End Sub


3.マクロ処理結果

2シート目、4シート目、6シート目の印刷プレビュー画面が表示されます。

印刷プレビュー


■マクロ解説

1.複数シートを印刷する(今回は印刷プレビュー)

Sheets(配列名).PrintPreview


st(0)="値あり1"

st(1)="値あり2"

st(2)="値あり3"

という配列があったととして、

Sheets(st).PrintPreview

とすると、中身は

Sheets(Array("値あり1","値あり2","値あり3")).PrintPreview

と同義となるので、シート「値あり1」、シート「値あり2」、シート「値あり3」が選択された状態で印刷プレビューがかかる


↓よろしければクリックをお願いします!



TOPページへ戻る


■社内DX案件紹介

【社内DX案件紹介】アンケートの集計-1-

【社内DX案件紹介】アンケートの集計-2-

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

【社内DX案件紹介】2つのファイルの内容を比較する

【社内DX案件紹介】封入物の重さによって印刷会社を変える

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する


■社内DXの進め方

【社内DXの進め方】ブログの目的(会社が求めるDX)

【社内DXの進め方】社内DXの推進について

【社内DXの進め方】社内DXは具体的に何をすればよいのか?

【社内DXの進め方】なぜ今Excelか?

2023年1月21日土曜日

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する

 ■社内DXの依頼内容

・2つのインプットファイルがあり、その中の複数シートのデータを、1つのアウトプットファイル、1シートに集約しXLSファイルとして出力したい

・処理漏れや誤処理厳禁のため、処理後に処理漏れ確認および誤処理検知できるような仕様としたい

A社B社2つのファイルを集約し、出力する


■社内DXの条件

1.2つのインプットファイル(A社ファイル,B社ファイル)は、2シート目から順に転記

2.インプットファイル、“対象期間(前)”と“対象期間(後)”の月数が、12か月以内のものは、そのまま転記し、13か月以上のものは"1月~12月”の表示形式で最大12か月の期間で行を分ける。(1行の内、期間は年を跨がない)

(例)「対象期間(前):2021年5月」「対象期間(後):2023年3月」の場合

対象期間(前)対象期間(後)
1行目20215202112
2行目20221202212
3行目2023120233

3.ファイルパス、ファイル数、ファイル名は固定(拡張子は.xlsx or .xls)。

4.シート数、シート名は変動有り(データ記載は2シート目~は固定)


■諸元

・インプットファイルを開く

・2シート目からの情報を取得する

・対象期間(前)と対象期間(後)の期間が12か月以内かどうか判断し、転記する
 なお13か月以上の場合は年単位で分割し転記する

・転記は検証用シート「処理結果」とアウトプット用シート「output」にそれぞれ転記することとし、「処理結果」で処理漏れがないか確認できるようにする

・アウトプット用シート「output」を新規ブックにコピーし.xls形式にて保存する


■作成方法

1.2シート目からデータのある2つのファイルを準備する。

  なおデータの配置は以下とします。
  ・A~D列:番号
  ・E列   :氏名
  ・F列   :対象期間(前)の年
  ・G列   :対象期間(前)の月
  ・H列   :対象期間(後)の年
  ・I列    :対象期間(後)の月

A社ファイル

B社ファイル

2.実際にマクロを書いていく

Sub Main()

Dim strFP   As String       '/--フォルダパス--/'
Dim strFN   As String       '/--ファイル名--/'
Dim mWB     As Workbook     '/--マクロのワークブック--/'
Dim iWB     As Workbook     '/--インプットファイルのワークブック--/'
Dim iWS     As Worksheet    '/--インプットファイルのワークシート--/'


Dim cWS As Integer          '/--シート数格納--/'
Dim s As Integer            '/--シート数カウンタ--/'
Dim n As Integer            '/--年周回カウンタ--/'
Dim y As Long               '/--インプットファイル 行カウンタ--/'
Dim yI As Long              '/--インプットファイル 行数格納--/'
Dim yO As Long              '/--アウトプットファイル 行数格納--/'
Dim yR As Long              '/--処理結果 行数格納--/'

Dim strNo1 As String        '/--番号1Block目--/'
Dim strNo2 As String        '/--番号2Block目--/'
Dim strNo3 As String        '/--番号3Block目--/'
Dim strNo4 As String        '/--番号4Block目--/'
Dim strName As String       '/--氏名--/'
Dim lngFromY As String      '/--対象期間(前)(年)--/'
Dim intFromM As String      '/--対象期間(前)(月)--/'
Dim dateFrom As Date        '/--対象期間(前)(年月)--/'
Dim lngToY As String        '/--対象期間(後)(年)--/'
Dim intToM As String        '/--対象期間(後)(月)--/'
Dim dateTo As Date          '/--対象期間(後)(年月)--/'
Dim lngDiffY As Long        '/--対象期間(年)--/'
Dim lngDiffM As Long        '/--対象期間(月)--/'

Set mWB = ActiveWorkbook
strFP = mWB.Sheets("メイン").Cells(2, 2).Value

'/--データが残ってたりしないよう、先にデータを消去--/'
mWB.Sheets("処理結果").Select
mWB.Sheets("処理結果").Range(Rows(3), Rows(Rows.Count)).Clear
mWB.Sheets("output").Select
mWB.Sheets("output").Range(Rows(2), Rows(Rows.Count)).Clear

yR = 3
yO = 2

strFN = Dir(strFP & "\*.xls*")

Do Until strFN = ""
    Select Case strFN
        '/--見つけたファイルがマクロファイルの場合は何もしない--/'
        Case mWB.Name
        
        '/--見つけたファイルがマクロファイル以外の場合--/'
        Case Else
            Set iWB = Workbooks.Open(strFP & "\ " & strFN)
            cWS = iWB.Worksheets.Count
            For s = 2 To cWS
                Set iWS = iWB.Sheets(s)
                strNo1 = ""
                strNo2 = ""
                strNo3 = ""
                strNo4 = ""
                strName = ""
                lngFromY = 0
                intFromM = 0
                lngToY = 0
                intToM = 0
                
                yI = iWS.Cells(Rows.Count, 1).End(xlUp).Row
                For y = 2 To yI
                    '/--インプット情報を取得--/'
                    strNo1 = iWS.Cells(y, 1)
                    strNo2 = iWS.Cells(y, 2)
                    strNo3 = iWS.Cells(y, 3)
                    strNo4 = iWS.Cells(y, 4)
                    strName = iWS.Cells(y, 5)
                    lngFromY = CLng(iWS.Cells(y, 6))
                    intFromM = CInt(iWS.Cells(y, 7))
                    lngToY = CLng(iWS.Cells(y, 8))
                    intToM = CInt(iWS.Cells(y, 9))
                    
                    '/--データの期間を計算--/'
                    dateFrom = DateSerial(lngFromY, intFromM, 1)
                    dateTo = DateSerial(lngToY, intToM, 1)
                    lngDiffM = DateDiff("m", dateFrom, dateTo)
                    
                    '/--検証用シートに共通項目だけ転記--/'
                    With mWB.Sheets("処理結果")
                        .Cells(yR, 1).Value = iWB.Name
                        .Cells(yR, 2).Value = iWS.Name
                        .Cells(yR, 3).Value = y
                        .Cells(yR, 4).Value = strNo1
                        .Cells(yR, 5).Value = strNo2
                        .Cells(yR, 6).Value = strNo3
                        .Cells(yR, 7).Value = strNo4
                        .Cells(yR, 8).Value = strName
                        .Cells(yR, 9).Value = lngFromY
                        .Cells(yR, 10).Value = intFromM
                        .Cells(yR, 11).Value = lngToY
                        .Cells(yR, 12).Value = intToM
                    End With
                    
                    '/--データ期間ごとの処理--/'
                    Select Case lngDiffM
                        Case Is < 12   '/--同月含む12か月以内の場合--/'
                            '/--検証用シートに1レコード分だけ転記--/'
                            With mWB.Sheets("処理結果")
                                .Cells(yR, 13).Value = lngFromY
                                .Cells(yR, 14).Value = intFromM
                                .Cells(yR, 15).Value = lngToY
                                .Cells(yR, 16).Value = intToM
                            End With
                            '/--アウトプット用シートに1レコード分だけ転記--/'
                            With mWB.Sheets("Output")
                                .Cells(yO, 1).Value = strNo1
                                .Cells(yO, 2).Value = strNo2
                                .Cells(yO, 3).Value = strNo3
                                .Cells(yO, 4).Value = strNo4
                                .Cells(yO, 5).Value = strName
                                .Cells(yO, 6).Value = lngFromY
                                .Cells(yO, 7).Value = intFromM
                                .Cells(yO, 8).Value = lngToY
                                .Cells(yO, 9).Value = intToM
                            End With
                            yR = yR + 1
                            yO = yO + 1
                            
                        Case Else      '/--同月含む13か月以上の場合--/'
                            
                            '/--何年跨いでいるかの期間を取得--/'
                            lngDiffY = DateDiff("yyyy", dateFrom, dateTo)
                            
                            '/--年跨ぎ分の周回処理--/'
                            For n = 0 To lngDiffY
                                '/--検証用シートに対象期間(年)+n年の情報を転記--/'
                                With mWB.Sheets("処理結果")
                                    .Cells(yR, n * 4 + 13).Value = lngFromY + n
                                    If n = 0 Then
                                        .Cells(yR, n * 4 + 14).Value = intFromM
                                    Else
                                        .Cells(yR, n * 4 + 14).Value = 1
                                    End If
                                    .Cells(yR, n * 4 + 15).Value = lngFromY + n
                                    If n = lngDiffY Then
                                        .Cells(yR, n * 4 + 16).Value = intToM
                                    Else
                                        .Cells(yR, n * 4 + 16).Value = 12
                                    End If
                                End With
                                
                                '/--アウトプット用シートに対象期間(年)+n年の情報を転記--/'
                                With mWB.Sheets("Output")
                                    .Cells(yO, 1).Value = strNo1
                                    .Cells(yO, 2).Value = strNo2
                                    .Cells(yO, 3).Value = strNo3
                                    .Cells(yO, 4).Value = strNo4
                                    .Cells(yO, 5).Value = strName
                                    .Cells(yO, 6).Value = lngFromY + n
                                    If n = 0 Then
                                        .Cells(yO, 7).Value = intFromM
                                    Else
                                        .Cells(yO, 7).Value = 1
                                    End If
                                    .Cells(yO, 8).Value = lngFromY + n
                                    If n = lngDiffY Then
                                        .Cells(yO, 9).Value = intToM
                                    Else
                                        .Cells(yO, 9).Value = 12
                                    End If
                                    yO = yO + 1
                                End With
                            Next n
                            yR = yR + 1
                    End Select
                    
                Next y
                Set iWS = Nothing
            Next s
    End Select
    iWB.Close
    Set iWB = Nothing
    strFN = Dir()
Loop

'/--アウトプット用シートを新規ブックにコピーして保存--/'
Application.DisplayAlerts = False
Sheets("Output").Select
Sheets("Output").Copy
ActiveWorkbook.SaveAs Filename:=strFP & "\output.xls", FileFormat:=xlExcel8
ActiveWindow.Close
Application.DisplayAlerts = True

Set mWB = Nothing

End Sub


3.マクロ処理結果

処理結果のシートには検証のデータが、

検証用のシート


Outputのシートには実際にファイル出力されるデータが転記され

出力されるシート


インプットファイルと同じフォルダにoutput.xlsというファイルが出力されます。

出力されたファイル


■マクロ解説

1.データの期間を計算

'/--データの期間を計算--/'
dateFrom = DateSerial(lngFromY, intFromM, 1)
dateTo = DateSerial(lngToY, intToM, 1)
lngDiffM = DateDiff("m", dateFrom, dateTo)

・dateFrom = DateSerial(lngFromY, intFromM, 1)

年(lngFromY)、月(intFromM)、日(1)で日付のシリアル値(1900/1/1からの経過日数)を日付型のdateFromへ格納しています。
lngFromY:対象期間(前)(年)
intFromM:対象期間(前)(月)
同じようにdateTo = DateSerial(lngToY, intToM, 1)で対象期間(後)の年月日も日付型で格納しています。

・lngDiffM = DateDiff("m", dateFrom, dateTo)

dateFromからdateToまでの期間を単位で計算し、数値型lngDiffMへ格納しています。


2.13か月以上の処理

lngDiffMが12以上(同月はlngDiffM=0となるので、13か月目は12となります。)は13か月以上として処理します。

'/--何年跨いでいるかの期間を取得--/'
lngDiffY = DateDiff("yyyy", dateFrom, dateTo)

'/--年跨ぎ分の周回処理--/'
For n = 0 To lngDiffY
    '/--アウトプット用シートにfrom対象期間+n年の情報を転記--/'
    With mWB.Sheets("Output")
        .Cells(yO, 1).Value = strNo1
        .Cells(yO, 2).Value = strNo2
        .Cells(yO, 3).Value = strNo3
        .Cells(yO, 4).Value = strNo4
        .Cells(yO, 5).Value = strName
        .Cells(yO, 6).Value = lngFromY + n
        If n = 0 Then
            .Cells(yO, 7).Value = intFromM
        Else
            .Cells(yO, 7).Value = 1
        End If
        .Cells(yO, 8).Value = lngFromY + n
        If n = lngDiffY Then
            .Cells(yO, 9).Value = intToM
        Else
            .Cells(yO, 9).Value = 12
        End If
        yO = yO + 1
    End With
Next n

・lngDiffY = DateDiff("yyyy", dateFrom, dateTo)

dateFromからdateToまでの期間を単位で計算し、数値型lngDiffMへ格納しています。
これにより何年跨いだかが判明します。

・For n = 0 To lngDiffY

跨いだ年数分周回させます。

・.Cells(yO, 6).Value = lngFromY + n

1年目はn=0なので「lngFromY:対象期間(前)(年)」の値が入り、
2年目はn=1となり「lngFromY」の1年後の年が入ります。
このようにnが+1されるごとに1年後の値が入るようになります。

・If n = 0 Then
.Cells(yO, 7).Value = intFromM
 Else
.Cells(yO, 7).Value = 1
 End If

1年目(n=0)は「intFromM:対象期間(前)(月)」の値が入りますが、2年目以降は対象期間(前)(月)は1月であるべきなので、n>0は1が入るようにしています。

・If n = lngDiffY Then
.Cells(yO, 9).Value = intToM
 Else
.Cells(yO, 9).Value = 12
 End If

最終年目(n=lngDiffY)は「intFromM:対象期間(後)(月)」の値が入りますが、最終年-1年目までは対象期間(後)(月)は12月であるべきなので、n<lngDiffYは12が入るようにしています。

・yO = yO + 1

意外と忘れがちですが、13か月以上の場合は年毎に分割(インプット1に対してアウトプット複数)なので、この周回の中で「yO:Outputシートの行」を+1していきます。


このようにDateSerial、DateDiffを組み合わせ期間を取得、その期間の中で年と月をどのよう表現すればよいか考えると条件にある

2.インプットファイル、“対象期間(前)”と“対象期間(後)”の月数が、12か月以内のものは、そのまま転記し、13か月以上のものは"1月~12月”の表示形式で最大12か月の期間で行を分ける。(1行の内、期間は年を跨がない)

を達成できるようになります。


↓よろしければクリックをお願いします!

TOPページへ戻る


■社内DX案件紹介

【社内DX案件紹介】アンケートの集計-1-

【社内DX案件紹介】アンケートの集計-2-

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

【社内DX案件紹介】2つのファイルの内容を比較する

【社内DX案件紹介】封入物の重さによって印刷会社を変える

【社内DX案件紹介】値の入っているシートのみ印刷する


■社内DXの進め方

【社内DXの進め方】ブログの目的(会社が求めるDX)

【社内DXの進め方】社内DXの推進について

【社内DXの進め方】社内DXは具体的に何をすればよいのか?

【社内DXの進め方】なぜ今Excelか?


2022年12月30日金曜日

【社内DX案件紹介】封入物の重さによって印刷会社を変える

 コスト削減において、もっとも大きいな削減は人件費となりますが、通常の業務を少しDXすることでコスト削減を図ることが可能です。


■社内DXの依頼内容

お客様に送る郵送物を、封入物の重さによって印刷会社1・2・3に分類しコスト削減を図りたい。

全ての封入物の重さから印刷会社を1~3で分類するマクロ


■社内DXの条件

・封入物はA~Eの5種類

 封入物A:2g

 封入物B:3g

 封入物C:5g

 封入物D:10g

 封入物E:15g


・郵送物の重さによって印刷会社を変える

 15g未満:印刷会社1

 35g未満:印刷会社2

 35g以上:印刷会社3


・リストは横方向に順不同で封入物が記載されている

封入物が記載された顧客リスト


■諸元

・封入物のリストから重さを検索する


・検索には連想配列(Dictionaryオブジェクト)を使用して検索を高速化する


・封入物の総重量によって印刷会社を1~3で設定


■作成方法

1.シート「リスト」に顧客情報と封入物のリストを用意(今回は項番1~100でセット)

シート「リスト」 封入物が順不同でセットされた100名分の顧客リスト

2.シート「封入物リスト」に封入物名と重さのリストを用意

シート「封入物リスト」 封入物A~Eとその重さが記載されたリスト

3.実際にマクロを書いていく

Sub Insatsu_List()
    Dim y As Long           '/--行周回用のカウンタ--/'
    Dim x As Integer        '/--列周回用のカウンタ--/'
    
    Dim dicFunyu As Object  '/--封入物の連想配列用オブジェクト--/'
    Dim strKey As String    '/--検索用キー格納--/'
    Dim lngOmosa As Long    '/--重さを格納--/'
    Dim strKaisha As String '/--印刷会社名--/'
    
    '/--オブジェクトを連想配列(Dictionary)としてセット--/'
    Set dicFunyu = CreateObject("Scripting.Dictionary")
    
    '/--連想配列作成--/'
    For y = 2 To 6
        strKey = Sheets("封入物リスト").Cells(y, 1).Value
        lngOmosa = Sheets("封入物リスト").Cells(y, 2).Value
        '/--連想配列に検索キー(strKey)と値(lngOmosa)を格納--/'
        dicFunyu.Add strKey, lngOmosa
    Next y
    
    '/--リスト内のデータに重さ、印刷会社を記入--/'
    For y = 2 To 101
        lngOmosa = 0
        For x = 3 To 7
            strKey = Sheets("リスト").Cells(y, x).Value
            lngOmosa = lngOmosa + dicFunyu.Item(strKey)
        Next x
        
        Sheets("リスト").Cells(y, 8) = lngOmosa
        
        Select Case lngOmosa
            Case Is < 15
                strKaisha = "1"
            Case Is < 35
                strKaisha = "2"
            Case Is >= 35
                strKaisha = "3"
        End Select
        
        Sheets("リスト").Cells(y, 9) = strKaisha
        
    Next y
    
    Set dicOmosa = Nothing
    
    
End Sub


■マクロ解説

1.連想配列の作成

    '/--オブジェクトを連想配列(Dictionary)としてセット--/'
    Set dicFunyu = CreateObject("Scripting.Dictionary")
    
    '/--連想配列作成--/'
    For y = 2 To 6
        strKey = Sheets("封入物リスト").Cells(y, 1).Value
        lngOmosa = Sheets("封入物リスト").Cells(y, 2).Value
        '/--連想配列に検索キー(strKey)と値(lngOmosa)を格納--/'
        dicFunyu.Add strKey, lngOmosa
    Next y

・Set dicFunyu = CreateObject("Scripting.Dictionary")

dicFunyuというオブジェクトをDictionaryとしてセットします。

※Officeの365とか、なぜか旧Verと参照設定が異なる場合があるので、基本参照設定を使わないで作成しています


dicFunyu.Add strKey, lngOmosa

連想配列に検索キー(strKey)と値(lngOmosa)を代入します。

ルールとしては必ず検索キー1に対して値1となること

Excel関数のVlookupとかみたいに検索キー1つに対して複数の値をとることはできません。

※アイデア次第でやる方法はいくつかありますが別の機会に。


2.重さの取得

            strKey = Sheets("リスト").Cells(y, x).Value
            lngOmosa = lngOmosa + dicFunyu.Item(strKey)


・strKey = Sheets("リスト").Cells(y, x).Value

strKey に封入物名を代入します。


・lngOmosa = lngOmosa + dicFunyu.Item(strKey)

検索キー(strKey)からItem(値)を取り出します。


いかがでしょうか。

このように、少しのアイデアで十分に社内DXが実現できるようになります。


↓よろしければクリックをお願いします!

TOPページへ戻る


■社内DX案件紹介

【社内DX案件紹介】アンケートの集計-1-

【社内DX案件紹介】アンケートの集計-2-

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

【社内DX案件紹介】2つのファイルの内容を比較する

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する

【社内DX案件紹介】値の入っているシートのみ印刷する


■社内DXの進め方

【社内DXの進め方】ブログの目的(会社が求めるDX)

【社内DXの進め方】社内DXの推進について

【社内DXの進め方】社内DXは具体的に何をすればよいのか?

【社内DXの進め方】なぜ今Excelか?

2022年12月27日火曜日

【社内DX案件紹介】2つのファイルの内容を比較する

 ■社内DXの依頼内容

100行50列のデータが入っている2つのファイルの内容を比較し、一致しないセルに色を付けたい


■社内DXの条件

・A、Bのファイルは同じフォーマットで作られている

・情報は100行50列の5000個のセルがあり、セルは空欄の場合もある

・A、Bそれぞれのセルの値が同じか調べ、異なる場合は片方のファイルのセルだけ色を付ける

・セルに色付けするファイルのみマクロで作成してもよい


■諸元

・マクロは使わず、条件付き書式で実施

・B側のファイルに新たにコピペシートを追加し、Aの値を張り付ける

・Bのファイルには条件付き書式にてコピペシートの値と比較して色を付ける

■作成方法

1.B2~AY101までのセルに値を入れる(今回は1~2をランダムで代入する)

AとBのファイルの値を比較

もしランダムの値を入れるサンプルを使いたい場合はマクロでこれを入れて下さい。
Sub RNDM()
Dim y As Long
Dim x As Integer
Dim l As Integer
Dim h As Long

l = 1
h = 2

Randomize

For y = 2 To 101
    For x = 2 To 51
        Cells(y, x).Value = Int((h - l + 1) * Rnd + l)
    Next x
Next y

End Sub


2.Aファイル側に新たにコピペシートを作成し、Bのシート内容をコピーする

Bファイルの内容をコピペシートに反映


3.シート「コピペシート」に条件付き書式を設定する

・値の範囲(B2~AY101)を選択する

・[ホーム]-[条件付き書式]-[新しいルール]

条件付き書式の進め方

・「数式を使用して、書式設定するセルを決定」を選択

・「次の数式を満たす場合に値を書式設定(O)」に次の値を入れる
 =B2<>Aファイル!B2
=B2<>Aファイル!B2

・「書式(F)...」をクリックし、着色する色を決める(今回は黄色)
セルの書式設定で黄色を選択

・OKで決定
黄色で決定

・Aファイルとコピペシートで値が異なるセルのみ黄色でハッチングされる
Aファイルとコピペシートで値が異なるセルのみ黄色でハッチング


このように、特にマクロを使わずとも、2つのファイルの比較を実施することができます。

↓よろしければクリックをお願いします!

TOPページへ戻る


■社内DX案件紹介

【社内DX案件紹介】アンケートの集計-1-

【社内DX案件紹介】アンケートの集計-2-

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

【社内DX案件紹介】封入物の重さによって印刷会社を変える

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する

【社内DX案件紹介】値の入っているシートのみ印刷する


■社内DXの進め方

【社内DXの進め方】ブログの目的(会社が求めるDX)

【社内DXの進め方】社内DXの推進について

【社内DXの進め方】社内DXは具体的に何をすればよいのか?

【社内DXの進め方】なぜ今Excelか?


2022年12月15日木曜日

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

 前回の続きで今回は実際にマクロを書いていきます。

前> 【社内DX案件紹介】架電内容ごとの情報振り分け-1-


今回作るマクロ

前回のおさらいですが、

依頼内容は

データベースの情報を条件ごとに振り分ける

という話をしました。

データベースの情報を架電内容ごとに振り分ける

実際の処理としてはシンプルで

1.シート「抽出データ」のデータを取得する

2.取得したデータを条件に合ったシートへ転記する

の2点。
処理の流れ 条件だけ赤字


ただこの「条件」の作り方が今回のポイントでIF文ではなく、各カラムの情報①~④を繋げて判定する方法で行きたいと思います。
分類の条件

まずは全体像です。
本当はデータベースからデータをとって分類し、最後エクセルのファイルで出力するのですが、今回はシート「抽出データ」にある架電内容のデータを各シート「パターンA」~「パターンL」に情報を転記するマクロとしました。
マクロのエクセルシート


次にマクロの全体です。
Sub Sample2()

Dim intSheet As Integer         '/--シート番号--/'
Dim strSheetName As String      '/--シート名--/'
Dim lngMaxY As Long             '/--シート「抽出データ」の最大行数--/'
Dim lngY As Long                '/--行周回用カウンタ--/'
Dim lngMaxY2 As Long            '/--転記先シートの最大行数--/'
Dim intMaxX As Integer          '/--シート「抽出データ」の最大列数--/'
Dim intX As Integer             '/--列周回用カウンタ--/'
Dim strKaden As String          '/--架電理由--/'
Dim strKoutei As String         '/--工程名称--/'
Dim strNAT As String            '/--NAT--/'
Dim strIshi As String           '/--意思確認--/'
Dim strHantei As String         '/--条件判定--/'

'/--シート「抽出データ」の最大行数・最大列数を取得--/'
lngMaxY = Sheets("抽出データ").Cells(Rows.Count, 1).End(xlUp).Row
intMaxX = Sheets("抽出データ").Cells(1, Columns.Count).End(xlToLeft).Column

'/--カラム名を各シートに転記--/'
For intSheet = 2 To ActiveWorkbook.Sheets.Count
    For intX = 1 To intMaxX
        Sheets(intSheet).Cells(1, intX).Value = Sheets("抽出データ").Cells(1, intX).Value
    Next intX
Next intSheet

'/--シート「抽出データ」の最大行数分周回--/'
For lngY = 2 To lngMaxY
    strSheetName = ""
    strKaden = "0"
    strKoutei = "0"
    strNAT = "0"
    strIshi = "0"
    strHantei = "0000"

    strKaden = Sheets("抽出データ").Cells(lngY, 1).Value
    strKoutei = Sheets("抽出データ").Cells(lngY, 15).Value
    strNAT = Sheets("抽出データ").Cells(lngY, 19).Value
    strIshi = Sheets("抽出データ").Cells(lngY, 20).Value
    
    '/--架電理由の条件格納--/'
    Select Case strKaden
        Case "自動更新"
            strKaden = "1"
        Case "OB対象外"
            strKaden = "1"
        Case "審査"
            strKaden = "1"
        Case "電話・資料請求"
            strKaden = "2"
        Case "窓口(新規)"
            strKaden = "3"
        Case "不明"
            strKaden = "4"
        Case "乗換"
            strKaden = "4"
        Case "利用率高"
            strKaden = "4"
        Case "未成年"
            strKaden = "4"
        Case "ハイクラス"
            strKaden = "5"
        Case Else
            strKaden = "9"
    End Select
    
    '/--工程名称の条件格納--/'
    Select Case strKoutei
        Case "電話・本人宛NAT"
            strKoutei = "1"
        Case "電話・事前不備有"
            strKoutei = "2"
        Case "電話・本人宛不備"
            strKoutei = "3"
        Case "電話・同意"
            strKoutei = "4"
        Case "電話・資料請求"
            strKoutei = "5"
        Case Else
            strKoutei = "9"
    End Select
    
    '/--NATの条件格納--/'
    If strNAT = "" Then
        strNAT = "1"
    Else
        strNAT = "9"
    End If
    
    '/--意思確認の条件格納--/'
    If strIshi = "1" Then
        strIshi = "1"
    Else
        strIshi = "9"
    End If
    
    '/--各条件を結合--/'
    strHantei = strKaden & strKoutei & strNAT & strIshi
    
    '/--条件によるパターン判定--/'
    Select Case Left(strHantei, 2)
        Case "11"
            Select Case strHantei
                Case "1111"
                    strSheetName = "パターンA"
                Case Else
                    strSheetName = "パターンL"
            End Select
        Case "12"
            strSheetName = "パターンB"
        Case "13"
            strSheetName = "パターンC"
        Case "14"
            strSheetName = "パターンD"
        Case "15"
            strSheetName = "パターンE"
        Case "21"
            strSheetName = "パターンG"
        Case "22"
            strSheetName = "パターンH"
        Case "23"
            strSheetName = "パターンF"
        Case Else
            Select Case Left(strHantei, 1)
                Case "3"
                    strSheetName = "パターンI"
                Case "4"
                    strSheetName = "パターンJ"
                Case "5"
                    strSheetName = "パターンK"
                Case Else
                    strSheetName = "パターンL"
            End Select
    End Select
    
    '/--転記先シートの最大行数を取得--/'
    lngMaxY2 = Sheets(strSheetName).Cells(Rows.Count, 1).End(xlUp).Row + 1
    
    '/--転記先シートへデータを転記--/'
    For intX = 1 To intMaxX
        Sheets(strSheetName).Cells(lngMaxY2, intX).Value = Sheets("抽出データ").Cells(lngY, intX).Value
    Next intX
        
Next lngY

End Sub

それぞれのパートで説明すると
'/--シート「抽出データ」の最大行数・最大列数を取得--/'
lngMaxY = Sheets("抽出データ").Cells(Rows.Count, 1).End(xlUp).Row
intMaxX = Sheets("抽出データ").Cells(1, Columns.Count).End(xlToLeft).Column
ここはシート「抽出データ」の1列目の値がある最終行1行目の値がある最終列を取得しています。
まず
.Cells(Rows.Count, 1).End(xlUp).Row
ですが、
Row.Count:Excelの最後の行(1048576)
1      :1列目
.End(xlUp):最後の行から上方向に
.Row    :値のある行番号をとる
こんな意味となります。

.Cells(1, Columns.Count).End(xlToLeft).Column
ここもほとんど同じで
Columns.Count:Excelの最後の列(16384)
.End(xlToLeft)  :最後の列から左方向に
.Column    :値のある列番号をとる
こんな意味となります。

'/--架電理由の条件格納--/'
Select Case strKaden
    Case "自動更新"
        strKaden = "1"
    Case "OB対象外"
        strKaden = "1"
    Case "審査"
        strKaden = "1"
    Case "電話・資料請求"
        strKaden = "2"
    Case "窓口(新規)"
        strKaden = "3"
    Case "不明"
        strKaden = "4"
    Case "乗換"
        strKaden = "4"
    Case "利用率高"
        strKaden = "4"
    Case "未成年"
        strKaden = "4"
    Case "ハイクラス"
        strKaden = "5"
    Case Else
        strKaden = "9"
End Select
ここは①架電理由を1~5、9で分類してstrKadenに入れています。
同様にstrKoutei(工程名称)、strNAT(NAT)、strIshi(意思確認)も下図の条件に合わせて分類していきます。
分類の条件 赤字でパターン番号付与

'/--各条件を結合--/'
strHantei = strKaden & strKoutei & strNAT & strIshi

'/--条件によるパターン判定--/'
Select Case Left(strHantei, 2)
    Case "11"
        Select Case strHantei
            Case "1111"
                strSheetName = "パターンA"
            Case Else
                strSheetName = "パターンL"
        End Select
    Case "12"
        strSheetName = "パターンB"
    Case "13"
        strSheetName = "パターンC"
    Case "14"
        strSheetName = "パターンD"
    Case "15"
        strSheetName = "パターンE"
    Case "21"
        strSheetName = "パターンG"
    Case "22"
        strSheetName = "パターンH"
    Case "23"
        strSheetName = "パターンF"
    Case Else
        Select Case Left(strHantei 1)
            Case "3"
                strSheetName = "パターンI"
            Case "4"
                strSheetName = "パターンJ"
            Case "5"
                strSheetName = "パターンK"
            Case Else
                strSheetName = "パターンL"
        End Select
End Select

ここからは実際にA~Lのパターン分けになります
①②③④を繋げたstrHanteiがどうだったか?をSelect文で分類していますが、
①②③④の値が
1111・・・パターンA
12xx・・・パターンB(xはどの値でもよい)
13xx・・・パターンC
14xx・・・パターンD
15xx・・・パターンE
23xx・・・パターンF
21xx・・・パターンG
22xx・・・パターンH
3xxx・・・パターンI
4xxx・・・パターンJ
5xxx・・・パターンK
それ以外・・パターンL
となります。

ここでポイントですが、パターンA、I~K以外は①②で判定できる。という点です。

なので基本は
Select Case Left(strHantei, 2)
で左2文字分で判定し、
Left(strHantei, 2)の値が”11”の時は
Select Case strHantei
    Case "1111"
        strSheetName = "パターンA"
    Case Else
        strSheetName = "パターンL"
End Select
で4文字全てを条件とし、逆にLeft(strHantei 2)の値が”23”以降であれば
Select Case Left(strHantei, 1)
    Case "3"
        strSheetName = "パターンI"
    Case "4"
        strSheetName = "パターンJ"
    Case "5"
        strSheetName = "パターンK"
    Case Else
        strSheetName = "パターンL"
End Select
で左1文字だけで判定することでパターンA~Lの全てを分類できるようになります。

'/--転記先シートの最大行数を取得--/'
lngMaxY2 = Sheets(strSheetName).Cells(Rows.Count, 1).End(xlUp).Row + 1

'/--転記先シートへデータを転記--/'
For intX = 1 To intMaxX
    Sheets(strSheetName).Cells(lngMaxY2, intX).Value = Sheets("抽出データ").Cells(lngY, intX).Value
Next intX
で最後は転記先のシートの最大行数を取得して、その1つ下(+1)したところに、その行の値を転記して1行分が終了します。
あとはそれをシート「抽出データ」の全レコードで実施して終了になります。

これで案件2の紹介は終了します。


↓よろしければクリックをお願いします!

2022年12月13日火曜日

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

 今回も実際に依頼された社内DX案件を紹介します。


■案件2 架電内容ごとの情報振り分け

依頼内容

社内のデータベースにあるコールセンターのデータを特定の条件で振り分けてもらいたいというもの。

今はスタッフが手作業で振り分けていたようだが、それをVBAで何とかしたい。というもの。

つまりこれを

データベースのデータを手作業で振り分け

こうしたいということ

データベースの情報を自動で振り分け

実際のデータはこんな感じなのですが、

約20列のデータベースのデータ

これを

・架電理由

・工程名称

・NAT

・意思確認

データベースの条件を取得する箇所

の値が以下の条件に当てはまるようなパターン処理が必要となる。

12パターンの条件分岐

というわけで今回はこんな処理をなるべくシンプルになるようなマクロを作成します。

今回作るマクロ

シート「抽出データ」にある情報をパターン毎に分類し、各シートへ転記するマクロ

実際の処理の流れは非常に簡単で

1.シート「抽出データ」のデータを取得する

2.取得したデータを条件に合ったシートへ転記する

処理のながれ

この2点だけです。

ただ、この”条件”が非常に厄介です。

処理のながれ 条件だけ赤字

先ほどの分類の条件をもう一度確認しますがこんな感じです。

分類の条件 再掲

これをフローチャートで表すとこんな感じで複雑です。

条件のフローチャート

更にこれをマクロで書くとこうなります。

    strKaden = 架電理由の値を格納

    strKoutei = 工程名称の値を格納

    strNAT = NATの値を格納

    strIshi = 意思確認の値を格納

とすると、

If strKaden = "自動更新" Or strKaden = "OB対象外" Or strKaden = "審査" Then
	If strKoutei = "電話・本人宛NAT" Then
		If strNAT = "" And strIshi = "1" Then
		strSheetName = "パターンA"
		Else
		strSheetName = "パターンL"
		End If
	ElseIf strKoutei = "電話・事前不備有" Then
		strSheetName = "パターンB"
	ElseIf strKoutei = "電話・本人宛不備" Then
		strSheetName = "パターンC"
	ElseIf strKoutei = "電話・同意" Then
		strSheetName = "パターンD"
	ElseIf strKoutei = "電話・資料請求" Then
		strSheetName = "パターンE"
	Else
		strSheetName = "パターンL"
	End If
ElseIf strKaden = "電話・資料請求" Then
	If strKoutei = "電話・本人宛NAT" Then
		strSheetName = "パターンG"
	ElseIf strKoutei = "電話・事前不備有" Then
		strSheetName = "パターンH"
	ElseIf strKoutei = "電話・本人宛不備" Then
		strSheetName = "パターンF"
	Else
		strSheetName = "パターンL"
	End If
ElseIf strKaden = "窓口(新規)" Then
	strSheetName = "パターンI"
ElseIf strKaden = "不明" Or strKaden = "乗換" Or strKaden = "利用率高" _ 
		Or strKaden = "未成年" Then
	strSheetName = "パターンJ"
ElseIf strKaden = "ハイクラス" Then
	strSheetName = "パターンK"
Else
	strSheetName = "パターンL"
End If

かなり見づらいコードになりますね。


なので、今回は少しやり方を変えて、

架電理由:①

工程名称:②

NAT:③

意思確認:④

として、①②③④の値からパターン分けしていきたいと思います。

分類の条件 各番号によるパターン化

どういう考え方かというと、ASN.1の列挙型(ENUMERATED)に近いのですが、

①架電理由=自動更新・・・1

②工程名称=電話・本人宛NAT・・・1

③NAT=空欄・・・1

④意思確認=1・・・1

である場合、①②③④は”1111”となります。

この①②③④が”1111”の時はパターンAと判定する。

①②③④が"12xx"の時はパターンB、"15xx"の時はパターンEとすることで、複雑な条件式を作らなくてもよくなり、また条件が増えた場合においても修正が簡易となります。

※xは不問(どんな値でもよい)


このような場合はどのように書いていくのか、次回は実際にコードを書いてみたいと思います。

↓よろしければクリックをお願いします!

次 > 【社内DX案件紹介】架電内容ごとの情報振り分け-2-


TOPページに戻る



■社内DX案件紹介

【社内DX案件紹介】アンケートの集計-1-

【社内DX案件紹介】アンケートの集計-2-

【社内DX案件紹介】2つのファイルの内容を比較する

【社内DX案件紹介】封入物の重さによって印刷会社を変える

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する

【社内DX案件紹介】値の入っているシートのみ印刷する


■社内DXの進め方

【社内DXの進め方】ブログの目的(会社が求めるDX)

【社内DXの進め方】社内DXの推進について

【社内DXの進め方】社内DXは具体的に何をすればよいのか?

【社内DXの進め方】なぜ今Excelか?


2022年11月21日月曜日

【社内DX案件紹介】アンケートの集計-2-

今回からは実際にプログラムを書いていきます。

前 > 【社内DX案件紹介】アンケートの集計-1-

今回作るマクロ

前回までのおさらいですが、今回の依頼内容は
「特定のフォルダにあるアンケートをデータベースに登録するフォーマットに変換するマクロを組んでもらいたい。」
というものになります。
依頼されたマクロのイメージ

 前回までは作るべきマクロの処理内容までやりましたが、
マクロの処理フローイメージ

実際にプログラミングをしていきますが、こんな感じのプログラムにしていきます。
1.CSVファイルを検索
2.ファイル名を取得
3.CSVファイルを開く
4.情報を取得
5.情報を転記(今回はマクロファイルの別シート「出力先」へ転記する)
インプットデータを基にした処理イメージ

まずは1.ファイルを検索と2.ファイル名を取得(Sub File_Kensaku())

'/--「特定のフォルダ」のフォルダパス--/'
Dim strFolder_Path As String
'/--検索されたcsvファイルのファイル名--/'
Dim strFile_Name As String
'/--シート「出力先」の最終行--/'
Dim lngMax_Row As Long
Sub File_Kensaku()
    
    '/--CSVファイルが入っているフォルダのパス--/'
    strFolder_Path = "C:\temp"
    '/--転記先(シート「出力先」)の最終行を数える--/'
    lngMax_Row = Sheets("出力先").Range("A1048576").End(xlUp).Row
    
    '/--画面の更新を止める--/'
    Application.ScreenUpdating = False
    
    '/--1.CSVファイルを検索 --/'
    '/--フォルダ「Folder_Path」内にあるcsvファイルを検索--/'
    strFile_Name = Dir(strFolder_Path & "\*.csv")
    
    '/--フォルダ内にファイルが無い(File_Nameのサイズが0)のときは終了--/'
    If Len(strFile_Name) = 0 Then
        Exit Sub
    End If
    
    '/--2.ファイル名を取得 --/'
    '/--検索されたファイルが無い(File_Nameのサイズが0)状態になるまでループ--/'
    Do Until Len(strFile_Name) = 0
        '/--ファイルを開く処理(CSV_Hiraku)を呼び出し--/'
        Call CSV_Hiraku
        '/--次のファイルを検索--/'
        strFile_Name = Dir()
    Loop
    
    '/--画面の更新を開始する--/'
    Application.ScreenUpdating = True
    
End Sub

それぞれの細かい式は多分調べれば出てくるので、ここでは簡単な解説だけ。
strFile_Name = Dir(strFolder_Path & "\*.csv")
こちらでまず1発目にstrFolder_Path(C:\temp)内にあるCSVファイルを検索します。
もしファイルがあれば、strFile_Nameにファイル名が入ります。

If Len(strFile_Name) = 0 Then
で、ひょっとしたらC:\temp内にCSVファイルが1つも無いかもしれないので、ファイルが無かったらExit Subで終了にしています。
If strFile_Name = ”” Thenでも良いと思うのですが、strFile_Name = NULLの時を想定してIf Len(strFile_Name) = 0 Then(strFile_Nameの中身の文字数が0)で作っています。

Do Until Len(strFile_Name) = 0
strFile_Nameに値が入っている間はループするようにしています。

Call CSV_Hiraku
2.ファイルを開く処理(CSV_Hiraku)を呼び出します。
CSV_Hirakuが終わると、また戻ってきます。

strFile_Name = Dir()
ここがファイル検索の肝の部分だと思います。
上では
Dir(strFolder_Path & "\*.csv")
と書いていましたが、今回は
Dir()
と括弧の中身が入っていない状態です。

この違いは
Dir(strFolder_Path & "\*.csv") ・・・ 最初から検索(過去検索されたものも含む)
Dir()              ・・・ 次を検索(過去検索されたものは除外)
となります。

strFile_Name = Dir()を繰り返すと次へ…次へ…となり、フォルダ内のCSVファイルが全て検索されることになります。
なので最終的には
Len(File_Name) = 0
となり、
Do Until Len(strFile_Name) = 0
のループを抜けることになります。

続いて、3.CSVファイルを開く~5.情報を転記(Sub CSV_Hiraku())

Sub CSV_Hiraku()
    '/--開くCSVファイルパス--/'
    Dim strHiraku_CSV As String
    '/--CSVファイルの1行分データ--/'
    Dim strGyo_Data As String
    '/--strGyo_Dataの配列格納用データ--/'
    Dim valHairetsu
    '/--valHairetsuの要素数(CSVの列数)--/'
    Dim intRetsu As Integer
    '/--会社名--/'
    Dim strKaisha As String
    '/--販売会社--/'
    Dim strHanbai As String
    '/--国外--/'
    Dim strKokugai As String
    '/--国内--/'
    Dim strKokunai As String
    '/--所見--/'
    Dim strShoken As String
    
    '/--intRetsuの周回用カウンタ--/'
    Dim x As Integer
    '/--シート「出力先」の書き込み行--/'
    Dim y As Long
    
    '/--検索されたCSVのフルパス--/'
    strHiraku_CSV = strFolder_Path & "\ " & strFile_Name
    
    '/--yに最終行を入れる--/'
    y = lngMax_Row
    
    '/--3.CSVファイルを開く--/'
    '/--CSVファイルをテキスト形式でNo1で開く--/'
    Open strHiraku_CSV For Input As #1
    '/--とりあえず1行読み込む(カラム名の部分)--/'
    Line Input #1, strGyo_Data
    
    '/--CSVファイルが最終行になるまでループ--/'
    Do Until EOF(1)
        '/--4.情報を取得--/'
        '/--変数を初期化--/'
        strKaisha = ""
        strHanbai = ""
        strKokugai = ""
        strKokunai = ""
        strShoken = ""
        x = 0
        
        '/--1行読み込む--/'
        Line Input #1, strGyo_Data
        
        '/--読み込んだ1行を配列に格納する--/'
        valHairetsu = Split(strGyo_Data, ",")
        
        '/--配列の要素数(CSVの列数)を取得する--/'
        intRetsu = UBound(valHairetsu)
        
        '/--配列の要素数(CSVの列数)分、周回する--/'
        For x = 0 To intRetsu
            Select Case x
                '/--valHairetsu(0)(会社名)のとき--/'
                Case 0
                    strKaisha = strKaisha & valHairetsu(x)
                '/--valHairetsu(1~4)(販売会社)のとき--/'
                Case Is <= 4
                    If Len(strHanbai) <> 0 Then
                        strHanbai = strHanbai & vbCrLf
                    End If
                    strHanbai = strHanbai & valHairetsu(x)
                '/--valHairetsu(5~8)(国外)のとき--/'
                Case Is <= 8
                    If Len(strKokugai) <> 0 Then
                        strKokugai = strKokugai & vbCrLf
                    End If
                    strKokugai = strKokugai & valHairetsu(x)
                '/--valHairetsu(9~12)(国内)のとき--/'
                Case Is <= 12
                    If Len(strKokunai) <> 0 Then
                        strKokunai = strKokunai & vbCrLf
                    End If
                    strKokunai = strKokunai & valHairetsu(x)
                '/--valHairetsu(13~16)(所見)のとき--/'
                Case Is <= 16
                    If Len(strShoken) <> 0 Then
                        strShoken = strShoken & vbCrLf
                    End If
                    strShoken = strShoken & valHairetsu(x)
            End Select
        Next x
        
        '/-- 5.情報を転記 --/'
        y = y + 1
        Sheets("出力先").Cells(y, 1).Value = strKaisha
        Sheets("出力先").Cells(y, 2).Value = strHanbai
        Sheets("出力先").Cells(y, 3).Value = strKokugai
        Sheets("出力先").Cells(y, 4).Value = strKokunai
        Sheets("出力先").Cells(y, 5).Value = strShoken
    Loop
    
    '/--シート「出力先」の最終行を更新--/'
    lngMax_Row = y
    
    '/--CSVファイルを閉じる--/'
    Close #1
End Sub

こちらについての解説
Open strHiraku_CSV For Input As #1
ここから「Close #1」までが「3.CSVファイルを開く」の部分になります。

処理としては、「開くCSVのフルパス(strHiraku_CSV)」をテキストモードで読み込んでいる。
ちなみにテキストファイルへ書き出すときはFor Output Asとなる。

#1はファイル番号1にテキストデータを読み込む。という意味。
複数のテキストファイルを開く場合(CSVファイルと読み込んで、別のCSVファイルに書き出す場合とか)は#1の部分を別の番号(#2とか)にすることで区別できる。
ちなみにこのファイル番号1は閉じるまでかなりの頻度で使用する。

Line Input #1, strGyo_Data
ファイル番号1(#1)のデータを1行読み込んで、strGyo_Dataへ代入する。
CSVファイルはカンマ区切り(,)で構成されているので、この時格納されるデータは
,販売会社,販売会社,販売会社,販売会社,国外,国外,国外,国外,国内,国内,国内,国内,所見,所見,所見,所見
このようになる。

Do Until EOF(1)
ここから「Loop」までが「4.情報を取得」の部分になります。
「3.CSVファイルを開く」のように別の部分に切り出して呼び出すほうがイメージつきやすいかもしれませんが、あまり意味がないと思い中に入れました。

処理としては、
ファイル番号1(#1)のデータが最後(最終行の次)になるまでループする。
Do Untilで~まで
EOF(End Of File)は最後(最終行の次)
EOF(この中)はファイル番号(#1)
となる。

Hairetsu = Split(strGyo_Data, ",")
strGyo_Dataに代入された1行分のデータをカンマ(,)を区切りとし配列(valHasiretsu)に格納します。
1行分の文字列データから指定の文字(今回は",")で配列が自動生成されるので、非常に便利です。が、自分で配列のサイズを決めないので配列内をループさせるときには注意が必要です。
ちなみに↑のGyo_Data(,販売会社,販売会社,販売会社,販売会社,国外,国外,国外,国外,国内,国内,国内,国内,所見,所見,所見,所見)だったとすると、valHairetuはこんな感じになります。

valHairetsu() = {,販売会社,販売会社,販売会社,販売会社,国外,国外,国外,国外
               ,国内,国内,国内,国内,所見,所見,所見,所見}

ちなみに数え方は0からなので、↑のだと
valHairetsu(0) = NULL
valHairetsu(1) = "販売会社"
となります。

intRetsu = UBound(valHairetsu)
配列(valHairetsu)のサイズをintRetsuに代入します。
↑で少し触れましたが、Splitで配列に格納した場合、配列のサイズがわからない場合があるのでUbound(配列)でサイズを調べます。
配列は0始まりなので。Uboundで調べたサイズも0からの数になります。

For x = 0 To intRetsu
Uboundで調べた配列サイズRetsuの分周回します。
今回は表形式のデータをこんな感じで周回するイメージです。
配列の中身イメージ


Select Case x
今何列目か?(xの値がいくつか?)によって処理を変えています。
上から順に判定されていくので、たとえ
Case Is <= 16(xが16以下)
であっても、その前に
Case Is <= 12(xが12以下)
があるので、
Case Is <= 16
で処理される条件はxが13~16のとき(13~16列目:所見の列)のみとなります。

それぞれのCaseで変数に値を代入しています。

If Len(strHanbai) <> 0 Then
何かの手違いで元のデータシートに値が重複している(販売会社が2つの欄に記載されているとか)場合があるかもしれません。
そういった場合、
strHanbai = valHairetsu(x)
とやってしまうと、値を上書きしてしまいミスがあったことにも気づけなくなるので、
If Len(strHanbai) <> 0 Then
で値が入っているか判定し、もし値が入っていたら
strHanbai = strHanbai & vbCrLf
で改行コード(vbCrLf)を入れています。
特に「所見」の列は必ず複数値が入っているので、
【申入内容】○○○○○○○
【理由】○○○○○○○
【受付媒体】○○○○○○○
【その他】○○○○○○○
となるように、
strShoken = strShoken & vbCrLf
で必ず改行コードを入れます。

Sheets("出力先").Cells(y, 1).Value = strKaisha
ここが「5.情報を転記」の部分になります。
For x = 0 To intRetsuで周回して取得した情報を転記しています。
別ファイルに書き出してもいいのですが、今回はマクロファイル内に値を転記することで結果をわかりやすくしてみました。


以上で案件の1つ目は終了です。


次回は案件の2つ目になります。





2022年11月17日木曜日

【社内DX案件紹介】アンケートの集計-1-

 今回からは実際に友人から依頼された案件とDX化について紹介していきます。

■案件1 アンケートの集計

依頼内容

友人の会社では毎日、指定のフォーマット(CSVファイル)でアンケートが届く。それをスタッフがデータベースに登録するフォーマットに加工し、登録している。

「特定のフォルダにあるアンケートをデータベースに登録するフォーマットに変換するマクロを組んでもらいたい。」というのが依頼内容になります。


イメージとしては

1.スタッフが特定のフォルダにあるCSVファイルを開き

2.手動でシステムに投入できるファイルへ転記する

手動でシステムに投入するイメージ

そのような作業を

1.マクロが特定のフォルダにあるCSVファイルを開き

2.自動でシステムに投入できるファイルへ転記する

自動でシステム投入用ファイルを作成するイメージ

この依頼内容をどう進めていくか紹介していきます。



フォーマット

・アンケートのフォーマット

アンケートのフォーマット表形式で表示される
こんな感じで縦横で情報がちりばめられています


・データベース取り込み用フォーマット(出力先のフォーマット)

出力先のフォーマット。リスト形式で保存される
各項目ごとにデータをまとめたフォーマットとなります。

今回はマクロファイルにそのまま転記されます。



処理内容

ここまでの情報を基に、処理する内容を整理します。

1.CSVファイルを開き、情報を取得する

2.CSVファイルから取得した情報を出力先フォーマットに合わせて転記する

処理内容イメージ1 ざっくりとしたイメージ


この2つを実行すればよいのですが、

1.CSVファイルを開き、情報を取得する

これをするために

1-a.特定のフォルダからCSVファイルを検索する

1-b.検索したCSVファイルを開く

1-c.開いたCSVファイルから情報を取得する

この3つの手順が必要になります。

処理内容イメージ2 1の内容を細分化


また、特定のフォルダ内には1つのCSVファイルだけあるとは限らないので

3.「1.」に戻る

が必要になります。

処理内容イメージ3 戻るの追加

ここで3.「1.」に戻るについてですが、実際に「1.」に戻る処理をしてもいいのですが、「1-a.」で検索するファイルが無くなったら終了なので、「1-a.」をメインに考えてみると一つの大きなループが出来上がります。

1-a. 特定のフォルダからCSVファイルを検索する

 1-b. 見つかったCSVファイルを開く

 1-c. 開いたCSVファイルから情報を取得する

 2.  CSVファイルから取得した情報を出力先フォーマットに合わせて転記する

処理内容イメージ4 ファイル検索にほかの処理を埋め込む


ここで「1-C」、「2」については1-bでファイルを開いたあとに発生するので、1-bの処理の中に含まれることになります。

1-a. 特定のフォルダからCSVファイルを検索する

 1-b. 見つかったCSVファイルを開く

  1-c. 開いたCSVファイルから情報を取得する

  2.  CSVファイルから取得した情報を出力先フォーマットに合わせて転記する

処理内容イメージ5 ファイルを開くの中に情報取得と転記を埋め込み


ここまでくると作るべきマクロが大体見えてきます。

大きな処理としては「ファイルを検索する処理」「ファイルを開く処理」、そしてファイルを開いたら「情報を取得する処理」「転記する処理」を作れば完成になります。

1. ファイルを検索する処理

 2. ファイルを開く処理

  2-1. 情報を取得する処理

  2-2. 転記する処理

作るべきマクロのイメージ1


あとはプログラムを書いていくだけですが、一つポイントが。

1. ファイルを検索する処理

2. ファイルを開く処理

2-1. 情報を取得する処理

2-2. 転記する処理

の順に一つの流れで記載してもいいのですが、

1. ファイルを検索する処理

2. ファイルを開く処理


この2つの処理は結構頻繁に使用するので、それぞれで作成しておくとこの先のマクロを組む際にも流用が簡単になります。

1. ファイルを検索する処理

「2.ファイルを開く処理」を呼び出す


2. ファイルを開く処理

2-1.情報を取得する処理

2-2.転記する処理

「1. ファイルを検索する処理」に戻る


「2.ファイルを開く処理」を呼び出す

次を検索し戻る

ファイルを開く以降を切り出し



あとはプログラムを書いていくだけですが、長くなったので分けます。

次 > 【社内DX案件紹介】アンケートの集計-2-


TOPページに戻る


■社内DX案件紹介

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

【社内DX案件紹介】2つのファイルの内容を比較する

【社内DX案件紹介】封入物の重さによって印刷会社を変える

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する

【社内DX案件紹介】値の入っているシートのみ印刷する