fork download
  1. Option Explicit
  2. Dim dicT As Object '辞書 キー:支店名+課名+項目名(A~N) 値:粗利の値の合計値
  3. Const Sheet1 As String = "1部ピボット"
  4. Const Sheet2 As String = "2部ピボット"
  5. Const Sheet3 As String = "3部ピボット"
  6. Dim Uri_book As String '粗利データブック名
  7. Dim trg_mm As Long '指定月
  8. Dim Jis_folder As String '実績フォルダ
  9. Dim Kei_folder As String '計画フォルダ
  10. Dim trg_col As Long '算出カラム番号
  11. Dim warnP As String '警告データ
  12. Dim item_tbl1 As Variant '1部の項目名テーブル
  13. Dim item_tbl2 As Variant '2部の項目名テーブル
  14. Dim item_tbl3 As Variant '3部の項目名テーブル
  15. Public Sub 拠点別粗利集計()
  16. Dim ws As Worksheet
  17. Dim mm, ext As Variant
  18. Dim t1, t2 As Variant
  19. Dim Uri_path As String
  20. Dim key As Variant
  21. Set dicT = CreateObject("Scripting.Dictionary")
  22. Set ws = Worksheets("粗利集計")
  23. '項目名テーブル作成
  24. item_tbl1 = Array("I", "J", "K")
  25. item_tbl2 = Array("L", "M", "N")
  26. item_tbl3 = Array("A", "B", "C", "D", "E", "F", "G", "H")
  27. mm = ws.Cells(2, "A").Value '集計月
  28. If mm = "" Or IsNumeric(mm) = False Then
  29. MsgBox ("集計月が不正")
  30. Exit Sub
  31. End If
  32. trg_mm = mm
  33. If trg_mm < 1 Or trg_mm > 12 Then
  34. MsgBox ("集計月(1-12)が範囲外")
  35. Exit Sub
  36. End If
  37. '集計月に対応するカラム位置を取得
  38. trg_col = GetColNumber(trg_mm)
  39. Jis_folder = ws.Cells(2, "B").Value '実績フォルダ名
  40. Uri_book = ws.Cells(2, "C").Value '粗利データファイル
  41. '拡張子のチェック
  42. ext = Right(LCase(Uri_book), 5)
  43. If ext <> ".xlsx" And ext <> ".xlsm" Then
  44. MsgBox ("粗利データファイル名が不正")
  45. Exit Sub
  46. End If
  47. Kei_folder = ws.Cells(2, "D").Value '計画フォルダ名
  48.  
  49. If Dir(Jis_folder, vbDirectory) = "" Then
  50. MsgBox ("実績フォルダが存在しません<" & Jis_folder & ">")
  51. Exit Sub
  52. End If
  53. If Dir(Kei_folder, vbDirectory) = "" Then
  54. MsgBox ("計画フォルダが存在しません<" & Kei_folder & ">")
  55. Exit Sub
  56. End If
  57. '粗利データブック名設定
  58. Uri_path = Jis_folder & "\" & Uri_book
  59. If Dir(Uri_path, vbNormal) = "" Then
  60. MsgBox (Uri_path & "が存在しません")
  61. Exit Sub
  62. End If
  63.  
  64. If MsgBox(trg_mm & "月の粗利を" & Uri_book & "から集計します", vbOKCancel) <> vbOK Then Exit Sub
  65. t1 = Timer
  66. Application.ScreenUpdating = False
  67. '再計算を手動に設定
  68. Application.Calculation = xlCalculationManual
  69. '売上明細ブック名オープン
  70. Workbooks.Open Uri_path
  71. Workbooks(Uri_book).Activate
  72. 'ピボットデータ読み込み
  73. Call readPivot(Sheet1)
  74. Call readPivot(Sheet2)
  75. Call readPivot(Sheet3)
  76. '再計算を自動に戻す
  77. Application.Calculation = xlCalculationAutomatic
  78. Workbooks(Uri_book).Saved = True
  79. Workbooks(Uri_book).Close
  80. '計画フォルダ内の全ブックを更新する
  81. Call UpdateAllBooks(Kei_folder)
  82. Application.ScreenUpdating = True
  83. t2 = Timer
  84. MsgBox ("処理完了 所要時間(秒)=" & t2 - t1)
  85. warnP = ""
  86. '未処理のピボットがあるなら表示する
  87. If dicT.count > 0 Then
  88. For Each key In dicT
  89. warnP = warnP & key & vbLf
  90. Next
  91. End If
  92. If warnP <> "" Then
  93. MsgBox ("ピボットの以下の部門(支店)|所属(課)|項目名(A~N)のデータが未処理です" & vbLf & warnP)
  94. End If
  95. End Sub
  96.  
  97. '計画フォルダ内の全てのブックを更新する
  98. Private Sub UpdateAllBooks(ByVal Kei_folder As String)
  99. Dim bookname As String
  100. bookname = Dir(Kei_folder & "\*.xlsx", vbNormal)
  101. If bookname = "" Then
  102. MsgBox (Kei_folder & "内に拠点別ブックが存在しません。")
  103. End
  104. End If
  105. '全てのブックを更新する
  106. Do While bookname <> ""
  107. Call Update1Book(Kei_folder, bookname)
  108. bookname = Dir()
  109. Loop
  110. End Sub
  111.  
  112. '1つのブックを更新する
  113. Private Sub Update1Book(ByVal Kei_folder As String, ByVal bookname As String)
  114. Dim ws As Worksheet
  115. Dim i As Long
  116. Application.Calculation = xlCalculationManual
  117. Workbooks.Open Kei_folder & "\" & bookname
  118. Set ws = Worksheets("拠点計")
  119. Call Update1Sheet(bookname, ws)
  120. Application.Calculation = xlCalculationAutomatic
  121. 'ブックを保存し、閉じる
  122. Workbooks(bookname).Save
  123. Workbooks(bookname).Close
  124. End Sub
  125. '1つのシートを更新する
  126. Private Sub Update1Sheet(ByVal bookname As String, ByVal ws As Worksheet)
  127. '拠点シートに値を設定する
  128. '3部
  129. Call set_value(bookname, ws, "A", 9)
  130. Call set_value(bookname, ws, "B", 10)
  131. Call set_value(bookname, ws, "C", 11)
  132. Call set_value(bookname, ws, "D", 12)
  133. Call set_value(bookname, ws, "E", 13)
  134. Call set_value(bookname, ws, "F", 14)
  135. Call set_value(bookname, ws, "G", 15)
  136. Call set_value(bookname, ws, "H", 16)
  137. '1部
  138. Call set_value(bookname, ws, "I", 18)
  139. Call set_value(bookname, ws, "J", 19)
  140. Call set_value(bookname, ws, "K", 20)
  141. '2部
  142. Call set_value(bookname, ws, "L", 22)
  143. Call set_value(bookname, ws, "M", 23)
  144. Call set_value(bookname, ws, "N", 24)
  145. End Sub
  146. '個人シートに値の設定を行う
  147. Private Sub set_value(ByVal bookname As String, ByVal ws As Worksheet, ByVal item As String, ByVal row As Long)
  148. Dim col As Long
  149. Dim key As String
  150. 'カラム位置の設定
  151. col = trg_col
  152. key = ws.Cells(2, "C").Value & "|" & ws.Cells(3, "C").Value & "|" & item
  153. If dicT.exists(key) = True Then
  154. ws.Cells(row, col).Value = dicT(key)
  155. '登録したキーの削除
  156. dicT.Remove (key)
  157. Else
  158. '該当データなし
  159. ws.Cells(row, col).Value = ""
  160. End If
  161. End Sub
  162. 'ピボットテーブル読み込み
  163. Private Sub readPivot(ByVal sheet_name As String)
  164. Dim index As Long
  165. Dim sh As Worksheet
  166. Dim maxrow As Long
  167. Dim row As Long
  168. Dim dmonth As String
  169. Dim key As String
  170. Dim item As String
  171. Dim arari As Variant
  172. Dim ret As Boolean
  173. index = 0
  174. dmonth = trg_mm & "月"
  175. Set sh = Worksheets(sheet_name)
  176. maxrow = sh.Cells(Rows.count, "A").End(xlUp).row 'Sheet1 A列最大行
  177. '3行から最終行まで繰り返す
  178. For row = 3 To maxrow
  179. '集計月に一致するなら、テーブルに格納する
  180. If sh.Cells(row, "A").Text = dmonth Then
  181. ret = False
  182. Select Case sheet_name
  183. Case Sheet1
  184. ret = get_arari1(sheet_name, sh, row, item, arari)
  185. Case Sheet2
  186. ret = get_arari2(sheet_name, sh, row, item, arari)
  187. Case Sheet3
  188. ret = get_arari3(sheet_name, sh, row, item, arari)
  189. End Select
  190. '集計対象なら集計する
  191. If ret = True Then
  192. '支店名+課名+項目名
  193. key = sh.Cells(row, "D").Value & "|" & sh.Cells(row, "E").Value & "|" & item
  194. If dicT.exists(key) = False Then
  195. '最初のデータ
  196. dicT(key) = arari
  197. Else
  198. '以降のデータ
  199. dicT(key) = dicT(key) + arari
  200. End If
  201. End If
  202. End If
  203. Next
  204. End Sub
  205. '1部の粗利取得
  206. Private Function get_arari1(ByVal sheet_name As String, ByVal sh As Worksheet, ByVal row As Long, ByRef item As String, ByRef arari As Variant) As Boolean
  207. Dim ix As Long
  208. get_arari1 = False
  209. Call checkvalue1(sheet_name, sh, row, "K")
  210. arari = sh.Cells(row, "K").Value
  211. Call checkvalue2(sheet_name, sh, row, "F", 1, 2, True)
  212. Call checkvalue2(sheet_name, sh, row, "G", 1, 1, True)
  213. If sh.Cells(row, "G").Value = 1 Then
  214. ix = 2
  215. Else
  216. If sh.Cells(row, "F").Value = "" Then Exit Function
  217. ix = sh.Cells(row, "F").Value - 1
  218. End If
  219. item = item_tbl1(ix)
  220. get_arari1 = True
  221. End Function
  222. '2部の粗利取得
  223. Private Function get_arari2(ByVal sheet_name As String, ByVal sh As Worksheet, ByVal row As Long, ByRef item As String, ByRef arari As Variant) As Boolean
  224. Dim ix As Long
  225. Call checkvalue1(sheet_name, sh, row, "H")
  226. arari = sh.Cells(row, "H").Value
  227. Call checkvalue2(sheet_name, sh, row, "B", 4, 6, False)
  228. ix = sh.Cells(row, "B").Value - 4
  229. item = item_tbl2(ix)
  230. get_arari2 = True
  231. End Function
  232. '3部の粗利取得
  233. Private Function get_arari3(ByVal sheet_name As String, ByVal sh As Worksheet, ByVal row As Long, ByRef item As String, ByRef arari As Variant) As Boolean
  234. Dim ix As Long
  235. Call checkvalue1(sheet_name, sh, row, "J")
  236. arari = sh.Cells(row, "J").Value
  237. Call checkvalue2(sheet_name, sh, row, "F", 1, 8, False)
  238. ix = sh.Cells(row, "F").Value - 1
  239. item = item_tbl3(ix)
  240. get_arari3 = True
  241. End Function
  242. 'データのニューメリックチェックを行う
  243. Private Sub checkvalue1(ByVal sheet_name As String, ByVal sh As Worksheet, ByVal row As Long, ByVal col As String)
  244. If IsNumeric(sh.Cells(row, col).Value) = False Then
  245. sh.Activate
  246. sh.Cells(row, col).Select
  247. Application.Calculation = xlCalculationAutomatic
  248. MsgBox (sheet_name & "のデータ不正、以下の情報をメモしてください" & vbLf & row & "行" & col & "列")
  249. MsgBox (sh.Cells(row, col).Text)
  250. End
  251. End If
  252. End Sub
  253. 'データのニューメリックチェックを行い、範囲チェックを行う
  254. Private Sub checkvalue2(ByVal sheet_name As String, ByVal sh As Worksheet, ByVal row As Long, ByVal col As String, ByVal lowval As Long, ByVal highval As Long, ByVal allow_sp As Boolean)
  255. If allow_sp = True And sh.Cells(row, col).Value = "" Then
  256. Exit Sub
  257. End If
  258. Call checkvalue1(sheet_name, sh, row, col)
  259. If sh.Cells(row, col).Value > highval Or sh.Cells(row, col).Value < lowval Then
  260. sh.Activate
  261. sh.Cells(row, col).Select
  262. Application.Calculation = xlCalculationAutomatic
  263. MsgBox (sheet_name & "のデータ不正、以下の情報をメモしてください" & vbLf & row & "行" & col & "列")
  264. MsgBox (sh.Cells(row, col).Text)
  265. End
  266. End If
  267. End Sub
  268.  
  269. '指定月から指定月対応のカラム位置(実績の計)を計算する
  270. 'カラム位置は1からの連番
  271. '10月= 9... 9月=80
  272. Private Function GetColNumber(ByVal mm As Long)
  273. Dim ix As Long
  274. Dim arr As Variant
  275. '1月、2月、3月、4月、4月、5月、6月、7月、8月、9月、10月、11月、12月の先頭からの相対位置
  276. arr = Array(4, 5, 6, 9, 10, 11, 13, 14, 15, 0, 1, 2)
  277. ix = arr(mm - 1)
  278. GetColNumber = 3 + 6 * ix + 6
  279. End Function
  280.  
  281.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty