2025-09-18

This commit is contained in:
Kenichiro NOGI 2025-09-18 15:52:11 +09:00
parent 6c249f62ea
commit 973ad0a0fe
13 changed files with 1363 additions and 0 deletions

3
XVBA/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"pleasanter-code-assist.enabled": false
}

View File

@ -0,0 +1,370 @@
Option Explicit
Sub 明細の抽出()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Application.ScreenUpdating = False
Call 抽出シートクリア("抽出")
Call 明細情報抽出("サッシ工事", "抽出")
Call 明細情報抽出("内部建具工事", "抽出")
Call 明細情報抽出("設備工事", "抽出")
Call 明細情報抽出("雑工事", "抽出")
Call 明細書シートに移動
Call 明細書印刷範囲設定
Application.ScreenUpdating = True
End Sub
' filepath: c:\Users\k.nogi\#GitHub\ken_nogi\pleasanter\develop\##実行予算承認WF\sites\scripts\抽出マクロ.vbs
Sub 明細情報抽出(Byval categoryName As String, Byval destSheetName As String)
Dim srcWs As Worksheet, destWs As Worksheet
Dim srcTbl As ListObject
Dim destRow As Long, i As Long
Dim colProduct As Integer, colPrice As Integer, colQty As Integer, colUnit As Integer, colUnitName As Integer
Dim 金額 As Double, subtotal As Double
Dim lastRow As Long
Dim isFirst As Boolean
'--- 対象のテーブル情報 ---
Dim srcSheetName As String
Dim srcTableName As String
srcSheetName = Range(categoryName).Value
srcTableName = Range(categoryName).Value
'--- 設定 ---
Set srcWs = ThisWorkbook.Sheets(srcSheetName)
Set destWs = ThisWorkbook.Sheets(destSheetName)
Set srcTbl = srcWs.ListObjects(srcTableName)
'列番号取得(列名は実際のものに合わせてください)
colProduct = srcTbl.ListColumns("商品名").Index
colPrice = srcTbl.ListColumns("単価").Index
colUnit = srcTbl.ListColumns("単位").Index
colQty = srcTbl.ListColumns("数量").Index
colUnitName = srcTbl.ListColumns("単位名").Index
'--- データ書き込み開始行の決定 ---
lastRow = destWs.Cells(destWs.Rows.Count, 1).End(xlUp).Row
If destWs.Cells(1, 1).Value = "" Then
' シートが空の場合
destRow = 1
isFirst = True
Else
destRow = lastRow + 1
isFirst = False
End If
'--- カテゴリ名・ヘッダー出力 ---
destWs.Cells(destRow, 1).Value = categoryName
destRow = destRow + 1
subtotal = 0
'--- データ抽出と金額計算 ---
For i = 1 To srcTbl.ListRows.Count
If srcTbl.DataBodyRange(i, colQty).Value > 0 Then
destWs.Cells(destRow, 1).Value = " " + srcTbl.DataBodyRange(i, colProduct).Value
destWs.Cells(destRow, 2).Value = srcTbl.DataBodyRange(i, colPrice).Value
destWs.Cells(destRow, 3).Value = srcTbl.DataBodyRange(i, colUnit).Value
destWs.Cells(destRow, 4).Value = srcTbl.DataBodyRange(i, colQty).Value
destWs.Cells(destRow, 5).Value = srcTbl.DataBodyRange(i, colUnitName).Value
金額 = srcTbl.DataBodyRange(i, colPrice).Value * srcTbl.DataBodyRange(i, colUnit).Value * srcTbl.DataBodyRange(i, colQty).Value
destWs.Cells(destRow, 6).Value = 金額
subtotal = subtotal + 金額
destRow = destRow + 1
End If
Next
'--- 小計行(商品名と同じ列に"小計" ---
destWs.Cells(destRow, 1).Value = " 小計"
destWs.Cells(destRow, 6).Value = subtotal
'MsgBox "抽出と金額計算が完了しました", vbInformation
End Sub
Sub 抽出シートクリア(Byval destSheetName As String)
Dim destWs As Worksheet
Set destWs = ThisWorkbook.Sheets(destSheetName)
destWs.Cells.ClearContents
End Sub
Sub シートの切り替え()
Application.ScreenUpdating = False
'全シート非表示
Call 全シート非表示
'必要なシートのみ表示
Call 指定シート表示("サッシ工事")
Call 指定シート表示("内部建具工事")
Call 指定シート表示("設備工事")
Call 指定シート表示("雑工事")
Application.ScreenUpdating = True
End Sub
Sub 全シート非表示()
Dim sheetNames As Variant
Dim i As Integer
sheetNames = Array("NBサッシ工事", "NB内部建具", "NB設備", "B雑工事", "N雑工事", "Aサッシ工事", "A内部建具", "A設備", "A雑工事")
For i = LBound(sheetNames) To UBound(sheetNames)
On Error Resume Next
ThisWorkbook.Sheets(sheetNames(i)).Visible = xlSheetHidden
On Error Goto 0
Next i
End Sub
Sub 指定シート表示(Byval shName As String)
Dim sh As String
sh = Range(shName).Value
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(sh)
ws.Visible = xlSheetVisible
End Sub
Sub 基本入力シートに戻る()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("基本入力")
ws.Activate
ws.Range("A1").Select
End Sub
Sub 見積書シートに移動()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("見積書")
ws.Activate
ws.Range("A1").Select
End Sub
Sub 明細書シートに移動()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("明細書")
ws.Activate
ws.Range("A1").Select
End Sub
Sub セル参照でシート移動(Byval sheetName As String)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(sheetName)
If ws.Visible = xlSheetHidden Or ws.Visible = xlSheetVeryHidden Then
Call シートの切り替え
End If
ws.Activate
ws.Range("F4").Select
End Sub
Sub サッシ工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("サッシ工事").Value)
End Sub
Sub 内部建具工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("内部建具工事").Value)
End Sub
Sub 設備工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("設備工事").Value)
End Sub
Sub 雑工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("雑工事").Value)
End Sub
Sub クリア()
ActiveSheet.Range("F4:F10000").ClearContents
End Sub
Sub 見積書明細書PDF出力()
Dim wsMitsumori As Worksheet, wsMeisai As Worksheet
Dim pdfFileName As String
Dim folderPath As String
Dim mitsumoriNo As String, koujiName As String, issueDate As String
Set wsMitsumori = ThisWorkbook.Sheets("見積書")
Set wsMeisai = ThisWorkbook.Sheets("明細書")
' 保存先フォルダ(必要に応じて変更)
folderPath = ThisWorkbook.Path & "\"
' ファイル名用情報取得
mitsumoriNo = Range("見積書番号").Value
koujiName = Range("工事名").Value
issueDate = Range("発行年月日").Value
' 日付を"yyyyMMddHHmmss"形式に
Dim dt As String
dt = Format(issueDate, "yyyymmdd-HHMMSS")
' ファイル名作成
pdfFileName = folderPath & mitsumoriNo & "■" & koujiName & "■" & dt & ".pdf"
' シートを配列で指定してPDF出力
Sheets(Array("見積書", "明細書")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfFileName, Quality:=xlQualityStandard
' 元のシートに戻る
Call 基本入力シートに戻る
MsgBox "PDF出力が完了しました。" & vbCrLf & pdfFileName, vbInformation
End Sub
Sub 明細書印刷範囲設定()
Dim ws As Worksheet
Dim lastRow As Long
Dim 合計Row As Long
Dim printStartRow As Long, printEndRow As Long
Set ws = ThisWorkbook.Sheets("明細書")
' B列の最終行取得
lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
' B列の最終行から上方向に「合計」を探す
合計Row = 0
Dim i As Long
For i = lastRow To 2 Step -1
If ws.Cells(i, "B").Value = "合計" Then
合計Row = i
Exit For
End If
Next i
If 合計Row = 0 Then
MsgBox "「合計」が見つかりません。", vbExclamation
Exit Sub
End If
printStartRow = 2
printEndRow = 合計Row + 3
ws.PageSetup.PrintArea = ws.Range("B" & printStartRow & ":F" & printEndRow).Address
'MsgBox "印刷範囲をF" & printStartRow & "F" & printEndRow & "に設定しました。", vbInformation
End Sub
Sub 入力内容をすべてクリア()
If MsgBox("基本情報および部材リストの選択をすべてクリアします、よろしいですか?", vbYesNo + vbQuestion, "確認") = vbNo Then
Exit Sub
End If
Call 基本入力のE列クリア
Call 複数シートF列クリア
End Sub
Sub 複数シートF列クリア()
Dim sheetNames As Variant
Dim i As Integer
Dim ws As Worksheet
sheetNames = Array("NBサッシ工事", "NB内部建具", "NB設備", "B雑工事", "N雑工事", "Aサッシ工事", "A内部建具", "A設備", "A雑工事")
For i = LBound(sheetNames) To UBound(sheetNames)
On Error Resume Next
Set ws = ThisWorkbook.Sheets(sheetNames(i))
If Not ws Is Nothing Then
ws.Range("F4:F10000").ClearContents
End If
Set ws = Nothing
On Error Goto 0
Next i
End Sub
Sub 基本入力のE列クリア()
Dim ws As Worksheet
Dim i As Long
Set ws = ThisWorkbook.Sheets("基本入力")
For i = 1 To 100
If ws.Cells(i, "B").Value = 1 Then
ws.Cells(i, "E").ClearContents
End If
Next i
End Sub
Sub ファイルを別名保存()
Dim folderPath As String
Dim koujiName As String
Dim dt As String
Dim saveFileName As String
' 保存先フォルダ(現在のブックと同じ場所)
folderPath = ThisWorkbook.Path & "\"
' 工事名取得
koujiName = Range("工事名").Value
' 日時取得yyyyMMdd-HHMMSS形式
dt = Format(Now, "yyyymmdd-HHMMSS")
' ファイル名作成
saveFileName = folderPath & "nBAH積算システム" & "■" & koujiName & "■" & dt & ".xlsm"
' 別名で保存
ThisWorkbook.SaveAs Filename:=saveFileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
MsgBox "ファイルを保存しました。" & vbCrLf & saveFileName, vbInformation
End Sub
Sub シート保護と非表示処理()
Dim ws As Worksheet
Dim pwd As String
pwd = ThisWorkbook.Sheets("基本入力").Range("Z10000").Value
Application.ScreenUpdating = False
' 全シートをパスワードで保護
For Each ws In ThisWorkbook.Worksheets
ws.Protect Password:=pwd, UserInterfaceOnly:=True
Next ws
' 指定以外のシートを非表示
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "見積書" And ws.Name <> "明細書" And ws.Name <> "基本入力" Then
ws.Visible = xlSheetHidden
Else
ws.Visible = xlSheetVisible
End If
Next ws
Application.ScreenUpdating = True
' 元のシートに戻る
Call 基本入力シートに戻る
ActiveSheet.Range("E4").Select
End Sub
Sub シート保護解除()
Dim ws As Worksheet
Dim pwd As String
pwd = ThisWorkbook.Sheets("基本入力").Range("Z10000").Value
Application.ScreenUpdating = False
' 全シートの保護を解除
For Each ws In ThisWorkbook.Worksheets
ws.Unprotect Password:=pwd
Next ws
Application.ScreenUpdating = True
' 元のシートに戻る
Call 基本入力シートに戻る
ActiveSheet.Range("E4").Select
End Sub

View File

@ -0,0 +1,4 @@
{
"apiKey": "c38903157cbffc30961f50bc29d0991a6cd8af495ab3009b05c5f98e82b2e61b94ba2d5c0a48fc518b1cd74c9e427b01051a228f670f3c5282544dfbec93db87",
"url": "https://neo999.next-hd.net/pleasanter/"
}

View File

@ -0,0 +1,272 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_メインスクリプト
@name :
@siteIds : 335011
@siteTitles : 実行予算WF申請
@disabled: false
*/
let pageLoading = 0;
let apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
let areaNotificationList = JSON.parse($('#areaNotificationList').val() || '{}');
let classNotificationList = JSON.parse($('#classNotificationList').val() || '{}');
//----------------------------------------------------------------------
//初期処理
window.addEventListener('load', function () {
if (pageLoading == 0) {
console.log('Window load Event');
$p.ex.onLoad();
}
});
$p.events.on_editor_load = function () {
if (pageLoading == 0) {
console.log('on Editor Load');
$p.ex.onLoad();
}
}
$p.ex.onLoad = function () {
//ロード開始
pageLoading = 1;
//初期処理
$p.ex.init();
}
//----------------------------------------------------------------------
$p.ex.init = function () {
console.log('initialize...');
//初期化
//初期表示
const classX = $('input[name="Results_ClassX"]:checked').val();
$p.ex.changeMode(classX);
console.log('initialize...done');
}
//ClassXの選択値を取得
$('input[name="Results_ClassX"]:radio').change(function () {
const selectedValue = $(this).val();
console.log('Results_ClassX changed:', selectedValue);
// 必要な処理をここに追加
$p.ex.changeMode(selectedValue);
});
$p.events.before_validate_Create = function (args) {
//新規作成時の処理
console.log('New Create...');
$p.ex.setUsers();
}
//保存前処理
$p.events.before_validate = function (args) {
console.log('Before Validate...');
const classX = $('input[name="Results_ClassX"]:checked').val();
switch (classX) {
case '1':
$p.set($('#Results_ClassY'), $('#Results_Date001').val());
$p.set($('#Results_Date002'), '');
$p.set($('#Results_Date003'), '');
$p.set($('#Results_Date004'), '');
$p.set($('#Results_Date005'), '');
$p.set($('#Results_Num001'), '');
break;
case '2':
$p.set($('#Results_ClassY'), $('#Results_Date002').val());
$p.set($('#Results_Date001'), '');
$p.set($('#Results_Date003'), '');
$p.set($('#Results_Date004'), '');
$p.set($('#Results_Date005'), '');
$p.set($('#Results_Num001'), '');
break;
case '3':
$p.set($('#Results_ClassY'), $('#Results_Date003').val());
$p.set($('#Results_Date001'), '');
$p.set($('#Results_Date002'), '');
$p.set($('#Results_Date004'), '');
$p.set($('#Results_Date005'), '');
$p.set($('#Results_Num001'), '');
break;
case '4':
$p.set($('#Results_ClassY'), $('#Results_Date004').val());
$p.set($('#Results_Date001'), '');
$p.set($('#Results_Date002'), '');
$p.set($('#Results_Date003'), '');
$p.set($('#Results_Date005'), '');
$p.set($('#Results_Num001'), '');
break;
case '5':
$p.set($('#Results_ClassY'), $('#Results_Date005').val());
$p.set($('#Results_Date001'), '');
$p.set($('#Results_Date002'), '');
$p.set($('#Results_Date003'), '');
$p.set($('#Results_Date004'), '');
$p.set($('#Results_Num001'), '');
break;
case '6':
$p.set($('#Results_ClassY'), $('#Results_Num001').val() + ' 回');
$p.set($('#Results_Date001'), '');
$p.set($('#Results_Date002'), '');
$p.set($('#Results_Date003'), '');
$p.set($('#Results_Date004'), '');
$p.set($('#Results_Date005'), '');
break;
default:
}
}
//保存後処理
$p.events.after_set = function (args) {
//初期処理
$p.ex.init();
}
//マスターシートからデータを取得
$p.on('change', 'ClassA', function () {
$p.ex.getMSSData();
});
//マスターシートの情報取得
$p.ex.getMSSData = function () {
let resultId = $("#Results_ClassA").val();
$p.apiGet({
'id': resultId,
'done': function (data) {
console.log(data);
if (data.Response.TotalCount == '1') {
let mssData = data.Response.Data[0];
console.log('MSSデータをセット');
// 工事名の末尾に「様」または空白があれば削除
let classQ = mssData.ClassHash.ClassQ || '';
classQ = classQ.replace(/[\s様]+$/, '');
if (classQ !== '') {
classQ = classQ + ' 様邸';
}
$p.set($('#Results_ClassB'), classQ); //工事名
$p.set($('#Results_ClassC'), mssData.ClassHash.ClassA); //契約コード
$p.set($('#Results_ClassI'), mssData.ClassHash.Class033); //契約ブランド
$p.set($('#Results_ClassJ'), mssData.ClassHash.Class043); //建物種類
//延床面積選択
let num016 = parseFloat(mssData.NumHash.Num016 || '0');
if (num016 < 21) {
$p.set($('#Results_ClassK'), '20坪'); //延床面積
} else if (num016 < 31) {
$p.set($('#Results_ClassK'), '2130坪'); //延床面積
} else if (num016 < 41) {
$p.set($('#Results_ClassK'), '3140坪'); //延床面積
} else if (num016 < 51) {
$p.set($('#Results_ClassK'), '4150坪'); //延床面積
} else {
$p.set($('#Results_ClassK'), '51坪'); //延床面積
}
$p.set($('#Results_ClassL'), mssData.ClassHash.Class036); //構造材
//承認図予定日
if (mssData.DateHash.DateH != '1899-12-30T00:00:00') {
let dateH = new Date(mssData.DateHash.DateH);
let dateHStr = dateH.getFullYear() + '/' + (dateH.getMonth() + 1).toString().padStart(2, '0') + '/' + dateH.getDate().toString().padStart(2, '0');
$p.set($('#Results_DateB'), dateHStr);
}
//着工予定日
if (mssData.DateHash.Date063 != '1899-12-30T00:00:00') {
let date063 = new Date(mssData.DateHash.Date063);
let date063Str = date063.getFullYear() + '/' + (date063.getMonth() + 1).toString().padStart(2, '0') + '/' + date063.getDate().toString().padStart(2, '0');
$p.set($('#Results_DateC'), date063Str);
}
$p.clearMessage();
$p.ex.setMyMessage('new-status-lime', 'マスターシートの情報を取得しました');
} else {
//既存データクリア
$p.clearMessage();
$p.ex.setMyMessage('new-status-red', 'マスターシートの情報を取得に失敗しました');
}
},
'fail': function (data) {
console.log(data);
//既存データクリア
$p.clearMessage();
$p.ex.setMyMessage('new-status-red', 'マスターシートの情報を取得に失敗しました');
}
});
}
$p.ex.setUsers = function () {
console.log(areaNotificationList);
console.log(classNotificationList);
//担当監督マスタ、通知先マスタの情報を元に、担当監督、通知先をセットする
let area = $('#Results_ClassD').val() || '';
let mode = $('#Results_ClassX').val() || '';
if (area != '' && mode != '') {
$p.set($('#Results_Class001'), areaNotificationList[area].list1);
$p.set($('#Results_Class002'), areaNotificationList[area].list2);
$p.set($('#Results_Class003'), areaNotificationList[area].list3);
$p.set($('#Results_Class004'), areaNotificationList[area].list4);
$p.set($('#Results_Class005'), classNotificationList[mode].list1);
$p.set($('#Results_Class006'), classNotificationList[mode].list2);
//最終承認者
$p.set($('#Results_Class010'), classNotificationList[mode].list3);
console.log('担当監督、通知先をセットしました');
} else {
console.log('担当監督、通知先のセットに失敗しました');
}
}
$p.ex.changeMode = function (mode) {
//
$('#Results_Date001Field').hide();
$('#Results_Date002Field').hide();
$('#Results_Date003Field').hide();
$('#Results_Date004Field').hide();
$('#Results_Date005Field').hide();
$('#Results_Num001Field').hide();
console.log('changeMode...');
// モード変更に伴う処理をここに追加
//const classX = $('#Results_ClassX').val();
switch (mode) {
case '1':
$('#Results_Date001Field').show();
break;
case '2':
$('#Results_Date002Field').show();
break;
case '3':
$('#Results_Date003Field').show();
break;
case '4':
$('#Results_Date004Field').show();
break;
case '5':
$('#Results_Date005Field').show();
break;
case '6':
$('#Results_Num001Field').show();
break;
default:
}
}

View File

@ -0,0 +1,37 @@
[
{
"TableName": "Users",
"View": {
"ColumnFilterExpressions": {
"UserId": "[@Class001]"
}
}
}
]
[
{
"TableName": "Users",
"View": {
"ColumnFilterExpressions": {
"UserId": "[@Class010]"
}
}
}
]
[
{
"TableName": "Users",
"View": {
"ColumnFilterHash": {
"DeptId": "26",
},
"ColumnSorterHash": {
"UserId": "asc"
}
}
}
]

View File

@ -0,0 +1,327 @@
Option Explicit
Sub 明細の抽出()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Application.ScreenUpdating = False
Call 抽出シートクリア("抽出")
Call 明細情報抽出("サッシ工事", "抽出")
Call 明細情報抽出("内部建具工事", "抽出")
Call 明細情報抽出("設備工事", "抽出")
Call 明細情報抽出("雑工事", "抽出")
Call 明細書シートに移動()
Call 明細書印刷範囲設定()
Application.ScreenUpdating = True
End Sub
' filepath: c:\Users\k.nogi\#GitHub\ken_nogi\pleasanter\develop\##実行予算承認WF\sites\scripts\抽出マクロ.vbs
Sub 明細情報抽出(Byval categoryName As String, Byval destSheetName As String)
Dim srcWs As Worksheet, destWs As Worksheet
Dim srcTbl As ListObject
Dim destRow As Long, i As Long
Dim colProduct As Integer, colPrice As Integer, colQty As Integer, colUnit As Integer, colUnitName As Integer
Dim 金額 As Double, subtotal As Double
Dim lastRow As Long
Dim isFirst As Boolean
'--- 対象のテーブル情報 ---
Dim srcSheetName As String
Dim srcTableName As String
srcSheetName = Range(categoryName).Value
srcTableName = Range(categoryName).Value
'--- 設定 ---
Set srcWs = ThisWorkbook.Sheets(srcSheetName)
Set destWs = ThisWorkbook.Sheets(destSheetName)
Set srcTbl = srcWs.ListObjects(srcTableName)
'列番号取得(列名は実際のものに合わせてください)
colProduct = srcTbl.ListColumns("商品名").Index
colPrice = srcTbl.ListColumns("単価").Index
colUnit = srcTbl.ListColumns("単位").Index
colQty = srcTbl.ListColumns("数量").Index
colUnitName = srcTbl.ListColumns("単位名").Index
'--- データ書き込み開始行の決定 ---
lastRow = destWs.Cells(destWs.Rows.Count, 1).End(xlUp).Row
If destWs.Cells(1, 1).Value = "" Then
' シートが空の場合
destRow = 1
isFirst = True
Else
destRow = lastRow + 1
isFirst = False
End If
'--- カテゴリ名・ヘッダー出力 ---
destWs.Cells(destRow, 1).Value = categoryName
destRow = destRow + 1
subtotal = 0
'--- データ抽出と金額計算 ---
For i = 1 To srcTbl.ListRows.Count
If srcTbl.DataBodyRange(i, colQty).Value > 0 Then
destWs.Cells(destRow, 1).Value = " " + srcTbl.DataBodyRange(i, colProduct).Value
destWs.Cells(destRow, 2).Value = srcTbl.DataBodyRange(i, colPrice).Value
destWs.Cells(destRow, 3).Value = srcTbl.DataBodyRange(i, colUnit).Value
destWs.Cells(destRow, 4).Value = srcTbl.DataBodyRange(i, colQty).Value
destWs.Cells(destRow, 5).Value = srcTbl.DataBodyRange(i, colUnitName).Value
金額 = srcTbl.DataBodyRange(i, colPrice).Value * srcTbl.DataBodyRange(i, colUnit).Value * srcTbl.DataBodyRange(i, colQty).Value
destWs.Cells(destRow, 6).Value = 金額
subtotal = subtotal + 金額
destRow = destRow + 1
End If
Next
'--- 小計行(商品名と同じ列に"小計" ---
destWs.Cells(destRow, 1).Value = " 小計"
destWs.Cells(destRow, 6).Value = subtotal
'MsgBox "抽出と金額計算が完了しました", vbInformation
End Sub
Sub 抽出シートクリア(Byval destSheetName As String)
Dim destWs As Worksheet
Set destWs = ThisWorkbook.Sheets(destSheetName)
destWs.Cells.ClearContents
End Sub
Sub シートの切り替え()
Application.ScreenUpdating = False
'全シート非表示
Call 全シート非表示
'必要なシートのみ表示
Call 指定シート表示("サッシ工事")
Call 指定シート表示("内部建具工事")
Call 指定シート表示("設備工事")
Call 指定シート表示("雑工事")
Application.ScreenUpdating = True
End Sub
Sub 全シート非表示()
Dim sheetNames As Variant
Dim i As Integer
sheetNames = Array("NBサッシ工事", "NB内部建具", "NB設備", "B雑工事", "N雑工事", "Aサッシ工事", "A内部建具", "A設備", "A雑工事")
For i = LBound(sheetNames) To UBound(sheetNames)
On Error Resume Next
ThisWorkbook.Sheets(sheetNames(i)).Visible = xlSheetHidden
On Error Goto 0
Next i
End Sub
Sub 指定シート表示(Byval shName As String)
Dim sh As String
sh = Range(shName).Value
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(sh)
ws.Visible = xlSheetVisible
End Sub
Sub 基本入力シートに戻る()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("基本入力")
ws.Activate
ws.Range("A1").Select
End Sub
Sub 見積書シートに移動()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("見積書")
ws.Activate
ws.Range("A1").Select
End Sub
Sub 明細書シートに移動()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("明細書")
ws.Activate
ws.Range("A1").Select
End Sub
Sub セル参照でシート移動(Byval sheetName As String)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(sheetName)
If ws.Visible = xlSheetHidden Or ws.Visible = xlSheetVeryHidden Then
Call シートの切り替え
End If
ws.Activate
ws.Range("F4").Select
End Sub
Sub サッシ工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("サッシ工事").Value)
End Sub
Sub 内部建具工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("内部建具工事").Value)
End Sub
Sub 設備工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("設備工事").Value)
End Sub
Sub 雑工事テーブルへ移動()
If Range("選択ブランド").Value = "" Then
MsgBox "ブランドが選択されていません。", vbExclamation
Exit Sub
End If
Call セル参照でシート移動(Range("雑工事").Value)
End Sub
Sub クリア()
ActiveSheet.Range("F4:F10000").ClearContents
End Sub
Sub 見積書明細書PDF出力()
Dim wsMitsumori As Worksheet, wsMeisai As Worksheet
Dim pdfFileName As String
Dim folderPath As String
Dim mitsumoriNo As String, koujiName As String, issueDate As String
Set wsMitsumori = ThisWorkbook.Sheets("見積書")
Set wsMeisai = ThisWorkbook.Sheets("明細書")
' 保存先フォルダ(必要に応じて変更)
folderPath = ThisWorkbook.Path & "\"
' ファイル名用情報取得
mitsumoriNo = Range("見積書番号").Value
koujiName = Range("工事名").Value
issueDate = Range("発行年月日").Value
' 日付を"yyyyMMddHHmmss"形式に
Dim dt As String
dt = Format(issueDate, "yyyymmdd-HHMMSS")
' ファイル名作成
pdfFileName = folderPath & mitsumoriNo & "■" & koujiName & "■" & dt & ".pdf"
' シートを配列で指定してPDF出力
Sheets(Array("見積書", "明細書")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfFileName, Quality:=xlQualityStandard
' 元のシートに戻る
Call 基本入力シートに戻る()
MsgBox "PDF出力が完了しました。" & vbCrLf & pdfFileName, vbInformation
End Sub
Sub 明細書印刷範囲設定()
Dim ws As Worksheet
Dim lastRow As Long
Dim 合計Row As Long
Dim printStartRow As Long, printEndRow As Long
Set ws = ThisWorkbook.Sheets("明細書")
' B列の最終行取得
lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
' B2から下方向に「合計」を探す
合計Row = 0
Dim i As Long
For i = 2 To lastRow
If IsError(ws.Cells(i, "B").Value) Or ws.Cells(i, "B").Value = CVErr(xlErrNA) Then
Continue For
End If
If ws.Cells(i, "B").Value = "合計" Then
合計Row = i
Exit For
End If
Next i
If 合計Row = 0 Then
MsgBox "「合計」が見つかりません。", vbExclamation
Exit Sub
End If
printStartRow = 2
printEndRow = 合計Row + 3
ws.PageSetup.PrintArea = ws.Range("B" & printStartRow & ":F" & printEndRow).Address
'MsgBox "印刷範囲をF" & printStartRow & "F" & printEndRow & "に設定しました。", vbInformation
End Sub
Sub 入力内容をすべてクリア()
If MsgBox("基本情報および部材リストの選択をすべてクリアします、よろしいですか?", vbYesNo + vbQuestion, "確認") = vbNo Then
Exit Sub
End If
Call 基本入力のE列クリア()
Call 複数シートF列クリア()
End Sub
Sub 複数シートF列クリア()
Dim sheetNames As Variant
Dim i As Integer
Dim ws As Worksheet
sheetNames = Array("NBサッシ工事", "NB内部建具", "NB設備", "B雑工事", "N雑工事", "Aサッシ工事", "A内部建具", "A設備", "A雑工事")
For i = LBound(sheetNames) To UBound(sheetNames)
On Error Resume Next
Set ws = ThisWorkbook.Sheets(sheetNames(i))
If Not ws Is Nothing Then
ws.Range("F4:F10000").ClearContents
End If
Set ws = Nothing
On Error Goto 0
Next i
End Sub
Sub 基本入力のE列クリア()
Dim ws As Worksheet
Dim i As Long
Set ws = ThisWorkbook.Sheets("基本入力")
For i = 1 To 100
If ws.Cells(i, "B").Value = 1 Then
ws.Cells(i, "E").ClearContents
End If
Next i
End Sub
Sub ファイルを別名保存()
Dim folderPath As String
Dim koujiName As String
Dim dt As String
Dim saveFileName As String
' 保存先フォルダ(現在のブックと同じ場所)
folderPath = ThisWorkbook.Path & "\"
' 工事名取得
koujiName = Range("工事名").Value
' 日時取得yyyyMMdd-HHMMSS形式
dt = Format(Now, "yyyymmdd-HHMMSS")
' ファイル名作成
saveFileName = folderPath & "nBAH積算システム" & "■" & koujiName & "■" & dt & ".xlsm"
' 別名で保存
ThisWorkbook.SaveAs Filename:=saveFileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
MsgBox "ファイルを保存しました。" & vbCrLf & saveFileName, vbInformation
End Sub

View File

@ -0,0 +1,114 @@
/*
@config :next999.json
@filename : ${psFileBasename}
@title :01_マスタデータ取得
@name :01_マスタデータ取得
@siteIds : 335011
@siteTitles : 実行予算WF申請
@disabled: false
*/
try {
//マスタデータ取得
getMasterData1();
getMasterData2();
} catch (error) {
context.Log(error);
}
//マスタデータ取得1
function getMasterData1() {
//担当監督マスタ
let masterTableId = '335031';
let data = {
"View": {
"ColumnSorterHash": {
"NumA": "asc"
}
}
}
let results = items.Get(masterTableId, JSON.stringify(data));
if (results.Length === 0) {
context.Log('担当監督マスタデータが見つかりませんでした。1');
return;
}
let areaNotificationList = {};
let count = 0;
for (let item of results) {
const area = item.ClassA;
const list1 = item.ClassB;
const list2 = item.ClassC;
const list3 = item.ClassD;
const list4 = item.ClassE;
areaNotificationList[area] = {
"list1": list1,
"list2": list2,
"list3": list3,
"list4": list4
};
count++;
}
//取得したデータをhiddenに格納
if (count > 0) {
hidden.Add('areaNotificationList', JSON.stringify(areaNotificationList));
context.Log('担当監督マスタデータ取得完了');
return;
} else {
context.Log('担当監督マスタデータが見つかりませんでした。2');
return;
}
}
//マスタデータ取得2
function getMasterData2() {
//通知先マスタ
let masterTableId = '335032';
let data = {
"View": {
"ColumnSorterHash": {
"NumA": "asc"
}
}
}
let results = items.Get(masterTableId, JSON.stringify(data));
if (results.Length === 0) {
context.Log('通知先マスタデータが見つかりませんでした。3');
return;
}
let classNotificationList = {};
let count = 0;
for (let item of results) {
const shubetu = item.ClassA;
const list1 = item.ClassB;
const list2 = item.ClassC;
const list3 = item.ClassD;
classNotificationList[shubetu] = {
"list1": list1,
"list2": list2,
"list3": list3
};
count++;
}
//取得したデータをhiddenに格納
if (count > 0) {
hidden.Add('classNotificationList', JSON.stringify(classNotificationList));
context.Log('通知先マスタデータ取得完了');
return;
} else {
context.Log('通知先マスタデータが見つかりませんでした。4');
return;
}
}

View File

@ -0,0 +1,30 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 01_基本スタイル設定
@name :
@siteIds : 335011
@siteTitles : 実行予算WF申請
@disabled: false
*/
/*見出しサイズ*/
.field-section {
font-size: 1.5em !important;
font-weight: bold !important;
height: auto;
}
/*項目の後ろの行間を少し狭める*/
.field-normal {
height: 35px;
}
.field-wide {
min-height: 35px;
padding: 0 10px 5px 0;
}
/*コメントのある項目の高さだけ少し広げる*/
div:has(.commentAdd).field-normal {
height: 50px;
}

View File

@ -0,0 +1,28 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 02_個別スタイル調整
@name :
@siteIds : 335011
@siteTitles : 実行予算WF申請
@disabled: false
*/
#Results_ClassXField {
font-size: 1.5em !important;
& label {
font-weight: bold !important;
}
& input[type="radio"] {
accent-color: #f00;
transform: scale(1.5);
margin-top: 8px;
margin-left: 10px;
}
}
label[for="Results_ClassX"] {
color: #f00 !important;
}

View File

@ -0,0 +1,109 @@
/*
@config : next999.json
@filename : ${psFileBasename}
@title : 99_読み取り専用処理
@name
@siteIds : 335011
@siteTitles : 実行予算WF申請
@disabled: false
*/
label.error {
pointer-events: none;
z-index: 100;
border-top: none !important;
}
.code-readonly {
pointer-events: none;
background-color: lightgrey;
font-weight: bold;
}
.code-readonly2,
.code-readonly2+button,
.code-readonly2+div.ui-icon,
.code-readonly3,
.code-readonly3+button,
.code-readonly3+div.ui-icon {
font-weight: bold;
&:active {
pointer-events: none;
}
a:not(.ui-spinner-button) {
pointer-events: auto;
}
}
.code-readonly2 select,
.code-readonly2 input,
.code-readonly2 button.ui-multiselect,
.code-readonly2 .control-markup,
.code-readonly2 .ui-spinner,
span[data-readonly="1"] {
pointer-events: none;
border: dashed 1px black !important;
background-color: lightgray !important;
color: black !important;
.ui-spinner-input {
border: none;
}
}
.code-readonly3 select,
.code-readonly3 input,
.code-readonly3 button.ui-multiselect,
.code-readonly3 .control-markup,
.code-readonly3 .ui-spinner {
pointer-events: none;
border: dashed 1px black !important;
.ui-spinner-input {
border: none;
}
}
.code-readonly2,
.code-readonly3,
.field-normal:has(span[data-readonly="1"]),
.field-wide:has(span[data-readonly="1"]) {
position: relative;
&:hover::after {
content: "読取り専用です";
position: absolute;
left: 120px;
top: calc(100% - 9px);
margin-top: 4px;
background: #00000080;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: normal !important;
pointer-events: none;
z-index: 9999;
white-space: nowrap;
}
}
.code-required,
select[data-validate-required="1"],
input[data-validate-required="1"] {
border: solid 2px red !important;
&+button.ui-multiselect {
border: solid 2px red !important;
}
}
label[class="required"] {
color: red !important;
font-weight: bold !important;
}

View File

@ -8,6 +8,75 @@
@disabled: false @disabled: false
*/ */
$p.ex.getMSSData = function () {
let resultId = $("#Results_ClassY").val();
$p.apiGet({
'id': resultId,
'done': function (data) {
console.log(data);
if (data.Response.TotalCount == '1') {
let mssData = data.Response.Data[0];
//既存データクリア
console.log('Clear MSS Data before Set');
$p.ex.clearMSSData();
console.log('Set MSS Data');
$p.set($('#Results_ClassZ'), mssData.ClassHash.ClassA); //契約コード
$p.set($('#Results_Class001'), mssData.ClassHash.Class001); //施主・姓
$p.set($('#Results_Class002'), mssData.ClassHash.Class002); //施主・名
$p.set($('#Results_Class003'), mssData.ClassHash.Class003); //施主・姓(カナ)
$p.set($('#Results_Class004'), mssData.ClassHash.Class004); //施主・名(カナ)
$p.set($('#Results_Class005'), mssData.ClassHash.ClassQ); //工事名
$p.set($('#Results_Class006'), mssData.ClassHash.ClassR); //工事名_カナ
$p.set($('#Results_Class010'), mssData.ClassHash.Class029); //建上地
$p.set($('#Results_Class011'), mssData.ClassHash.ClassW); //エリア
$p.set($('#Results_Class012'), mssData.ClassHash.Class033); //契約ブランド
$p.set($('#Results_Class013'), mssData.ClassHash.Class040); //防火指定
$p.set($('#Results_Class014'), mssData.ClassHash.Class043); //建物種類
$p.set($('#Results_Class021'), mssData.ClassHash.ClassF); //契約営業所
$p.set($('#Results_Class022'), mssData.ClassHash.ClassG); //主担当営業
$p.set($('#Results_Class023'), mssData.ClassHash.ClassH); //副担当営業
$p.set($('#Results_Class024'), mssData.ClassHash.ClassI); //営業設計
$p.set($('#Results_Class025'), mssData.ClassHash.ClassJ); //担当監督
$p.set($('#Results_Class026'), mssData.ClassHash.ClassK); //担当IC
$p.set($('#Results_Class027'), mssData.ClassHash.ClassL); //管理設計
$p.set($('#Results_Class028'), mssData.ClassHash.ClassY); //所属長
if (mssData.DateHash.DateH != '1899-12-30T00:00:00') {
let dateH = new Date(mssData.DateHash.DateH);
let dateHStr = dateH.getFullYear() + '/' + (dateH.getMonth() + 1).toString().padStart(2, '0') + '/' + dateH.getDate().toString().padStart(2, '0');
$p.set($('#Results_Date001'), dateHStr);
}
if (mssData.DateHash.Date063 != '1899-12-30T00:00:00') {
let date063 = new Date(mssData.DateHash.Date063);
let date063Str = date063.getFullYear() + '/' + (date063.getMonth() + 1).toString().padStart(2, '0') + '/' + date063.getDate().toString().padStart(2, '0');
$p.set($('#Results_Date002'), date063Str);
}
$p.set($('#Results_ClassS'), '1'); //案件状況
$p.clearMessage();
$p.ex.setMyMessage('new-status-lime', 'マスターシートの情報を取得しました');
} else {
//既存データクリア
$p.ex.clearMSSData();
}
},
'fail': function (data) {
console.log(data);
//既存データクリア
$p.ex.clearMSSData();
}
});
}
//MSSからの引用データをクリア //MSSからの引用データをクリア
$p.ex.clearMSSData = function () { $p.ex.clearMSSData = function () {