From 3582a67422ae7f63c49757669048126ecee359e0 Mon Sep 17 00:00:00 2001 From: "gigi.mamaladze" Date: Fri, 12 Dec 2025 19:44:06 +0400 Subject: [PATCH] Create DPM compare script and updated DPM Netwrok table script --- AutoCAD/Compare/DPM/DPM_device.xlsx | Bin 0 -> 10307 bytes AutoCAD/Compare/DPM/check_dpm_devices.py | 225 +++++++++++++ AutoCAD/Compare/DPM/device_list.xlsx | Bin 0 -> 7596 bytes AutoCAD/Compare/DPM/results.xlsx | Bin 0 -> 7186 bytes AutoCAD/Compare/{ => IO}/IO_Connection.xlsx | Bin AutoCAD/Compare/{ => IO}/Results.xlsx | Bin .../Compare/{ => IO}/check_io_vs_devices.py | 0 AutoCAD/Compare/{ => IO}/device_list.xlsx | Bin AutoCAD/DPM/MCM01_NETWORK.xlsx | Bin 7088 -> 9325 bytes AutoCAD/DPM/OUTPUT.xlsx | Bin 7529 -> 7529 bytes AutoCAD/DPM/build_network_tables.py | 21 +- AutoCAD/RenAttrib.LSP | 314 ++++++++++++++++++ 12 files changed, 554 insertions(+), 6 deletions(-) create mode 100644 AutoCAD/Compare/DPM/DPM_device.xlsx create mode 100644 AutoCAD/Compare/DPM/check_dpm_devices.py create mode 100644 AutoCAD/Compare/DPM/device_list.xlsx create mode 100644 AutoCAD/Compare/DPM/results.xlsx rename AutoCAD/Compare/{ => IO}/IO_Connection.xlsx (100%) rename AutoCAD/Compare/{ => IO}/Results.xlsx (100%) rename AutoCAD/Compare/{ => IO}/check_io_vs_devices.py (100%) rename AutoCAD/Compare/{ => IO}/device_list.xlsx (100%) create mode 100644 AutoCAD/RenAttrib.LSP diff --git a/AutoCAD/Compare/DPM/DPM_device.xlsx b/AutoCAD/Compare/DPM/DPM_device.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8040c0ed83b679c353ad0718d1470732db0623bb GIT binary patch literal 10307 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 literal 0 HcmV?d00001 diff --git a/AutoCAD/Compare/DPM/check_dpm_devices.py b/AutoCAD/Compare/DPM/check_dpm_devices.py new file mode 100644 index 0000000..a64a24d --- /dev/null +++ b/AutoCAD/Compare/DPM/check_dpm_devices.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +""" +Script to compare device lists from two Excel files. +- File 1: Extract all values from P_TAG1 column +- File 2: Extract all devices, ignoring those containing "SPARE" +- Output: Excel file with all devices and a YES/NO column indicating if device is in both files +""" + +import argparse +import sys +import pandas as pd +from pathlib import Path + + +def extract_from_p_tag1_file(file_path, sheet_name=0): + """ + Extract all device values from the P_TAG1 column. + + Args: + file_path: Path to Excel file with P_TAG1 column + sheet_name: Sheet name or index to read + + Returns: + List of device names (preserving original case) + """ + try: + df = pd.read_excel(file_path, sheet_name=sheet_name) + + # Find P_TAG1 column + if 'P_TAG1' not in df.columns: + print(f"Error: Column 'P_TAG1' not found in '{file_path}'") + print(f"Available columns: {list(df.columns)}") + sys.exit(1) + + # Extract all values from P_TAG1 column, preserving original case + devices = df['P_TAG1'].dropna().astype(str).str.strip() + devices = devices[devices != ''].tolist() + + return devices + except FileNotFoundError: + print(f"Error: File '{file_path}' not found.") + sys.exit(1) + except Exception as e: + print(f"Error reading '{file_path}': {e}") + sys.exit(1) + + +def extract_from_devices_file(file_path, sheet_name=0): + """ + Extract all devices from file, ignoring those containing "SPARE". + + Args: + file_path: Path to Excel file with device list + sheet_name: Sheet name or index to read + + Returns: + List of device names (preserving original case) + """ + try: + df = pd.read_excel(file_path, sheet_name=sheet_name) + + # Get all values from first column (assuming devices are in first column) + devices = df.iloc[:, 0].dropna().astype(str).str.strip() + devices = devices[devices != ''].tolist() + + # Also check if column name itself is a device (if it looks like a device name) + column_name = str(df.columns[0]).strip() + column_lower = column_name.lower() + + # If column name looks like a device (contains underscore, not "P_TAG1"), add it + if '_' in column_name and len(column_name) > 3 and column_lower != 'p_tag1': + if column_name not in devices: + devices.append(column_name) + + # Filter out devices containing "SPARE" (case-insensitive) + filtered_devices = [] + for device in devices: + device_lower = device.lower() + if 'spare' not in device_lower: + filtered_devices.append(device) + + return filtered_devices + except FileNotFoundError: + print(f"Error: File '{file_path}' not found.") + sys.exit(1) + except Exception as e: + print(f"Error reading '{file_path}': {e}") + sys.exit(1) + + +def compare_and_create_output(file1_path, file2_path, output_path, sheet1=0, sheet2=0): + """ + Compare device lists and create Excel output file. + + Args: + file1_path: Path to file with P_TAG1 column + file2_path: Path to file with device list + output_path: Path to output Excel file + sheet1: Sheet name or index for first file + sheet2: Sheet name or index for second file + """ + # Get file names (without path) for column headers + file1_name = Path(file1_path).name + file2_name = Path(file2_path).name + + print(f"Reading '{file1_path}' (looking for P_TAG1 column)...") + devices1 = extract_from_p_tag1_file(file1_path, sheet_name=sheet1) + print(f" Found {len(devices1)} devices in P_TAG1 column") + + print(f"Reading '{file2_path}' (extracting all devices, ignoring SPARE)...") + devices2 = extract_from_devices_file(file2_path, sheet_name=sheet2) + print(f" Found {len(devices2)} devices (after filtering SPARE)") + + # Create sets for case-insensitive comparison + devices1_lower = {d.lower(): d for d in devices1} + devices2_lower = {d.lower(): d for d in devices2} + + # Get all unique devices (combining both lists, preserving original case) + all_devices_lower = set(devices1_lower.keys()) | set(devices2_lower.keys()) + + # Create result list with original case + result_data = [] + for device_lower in sorted(all_devices_lower): + # Get original case (prefer from file1, then file2) + if device_lower in devices1_lower: + device_original = devices1_lower[device_lower] + else: + device_original = devices2_lower[device_lower] + + # Check if device is in each file (case-insensitive) + in_file1 = device_lower in devices1_lower + in_file2 = device_lower in devices2_lower + in_both = in_file1 and in_file2 + + result_data.append({ + 'Device': device_original, + file1_name: "YES" if in_file1 else "NO", + file2_name: "YES" if in_file2 else "NO", + 'In Both Files': "YES" if in_both else "NO" + }) + + # Create DataFrame + result_df = pd.DataFrame(result_data) + + # Validate output file extension + output_path_obj = Path(output_path) + if output_path_obj.suffix.lower() not in ['.xlsx', '.xls']: + # If no extension or wrong extension, add .xlsx + if not output_path_obj.suffix: + output_path = str(output_path_obj) + '.xlsx' + print(f"Note: Output file extension added: {output_path}") + else: + print(f"Warning: Output file should be .xlsx format. Converting to .xlsx") + output_path = str(output_path_obj.with_suffix('.xlsx')) + + # Write to Excel + try: + # Ensure openpyxl is available + try: + import openpyxl + except ImportError: + print("Error: openpyxl library is required. Install it with: pip install openpyxl") + sys.exit(1) + + result_df.to_excel(output_path, index=False, engine='openpyxl') + print(f"\nOutput saved to: {output_path}") + print(f"Total devices: {len(result_df)}") + print(f"Devices in both files: {len(result_df[result_df['In Both Files'] == 'YES'])}") + print(f"Devices only in one file: {len(result_df[result_df['In Both Files'] == 'NO'])}") + print(f"\nColumns in output file:") + print(f" - Device: Device name") + print(f" - {file1_name}: YES if device is in this file") + print(f" - {file2_name}: YES if device is in this file") + print(f" - In Both Files: YES if device is in both files") + except Exception as e: + print(f"Error writing to Excel file: {e}") + print(f"Make sure the output path is valid and you have write permissions.") + sys.exit(1) + + +def main(): + parser = argparse.ArgumentParser( + description='Compare device lists from two Excel files and create Excel output', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + python check_dpm_devices.py file1.xlsx file2.xlsx output.xlsx + python check_dpm_devices.py file1.xlsx file2.xlsx output.xlsx --sheet1 "Sheet1" --sheet2 "Sheet2" + """ + ) + + parser.add_argument('file1', type=str, + help='Path to first Excel file (must have P_TAG1 column)') + parser.add_argument('file2', type=str, + help='Path to second Excel file (device list, SPARE devices will be ignored)') + parser.add_argument('output', type=str, + help='Path to output Excel file (must be .xlsx format)') + parser.add_argument('--sheet1', type=str, default=0, + help='Sheet name or index for first file (default: 0)') + parser.add_argument('--sheet2', type=str, default=0, + help='Sheet name or index for second file (default: 0)') + + args = parser.parse_args() + + # Validate files exist + if not Path(args.file1).exists(): + print(f"Error: File '{args.file1}' does not exist.") + sys.exit(1) + + if not Path(args.file2).exists(): + print(f"Error: File '{args.file2}' does not exist.") + sys.exit(1) + + # Compare and create output + compare_and_create_output( + args.file1, + args.file2, + args.output, + sheet1=args.sheet1, + sheet2=args.sheet2 + ) + + +if __name__ == '__main__': + main() diff --git a/AutoCAD/Compare/DPM/device_list.xlsx b/AutoCAD/Compare/DPM/device_list.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..67c132e965427b2751ba507d2ca14a4cd124bb60 GIT binary patch literal 7596 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 MfJ{Ceq)*U)0eF(DQUCw| literal 0 HcmV?d00001 diff --git a/AutoCAD/Compare/DPM/results.xlsx b/AutoCAD/Compare/DPM/results.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8a87f9b72ff14dad6510a0dbaf91b8a58e861c53 GIT binary patch literal 7186 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 literal 7088 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 MLmB*9B}9z>4F_O!m;e9( delta 3559 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 Z!7cp{o?qGJ^T_?o@-vU-&mG2#`VWA8emejF diff --git a/AutoCAD/DPM/build_network_tables.py b/AutoCAD/DPM/build_network_tables.py index 7089e75..43eefbe 100644 --- a/AutoCAD/DPM/build_network_tables.py +++ b/AutoCAD/DPM/build_network_tables.py @@ -162,9 +162,12 @@ def generate_rows(unique_dpms, assign, rating_map, net2_dpms): for dpm in unique_dpms: ring_ip = ring_ip_map[dpm] tags = assign.get(dpm, []) - tags = tags[:24] + ["SPARE"] * (24 - len(tags[:24])) + + # Generate ports starting from 5, continuing beyond 28 if needed + num_devices = len(tags) + ports = list(range(5, 5 + num_devices)) - for idx, port in enumerate(range(5, 29)): + for idx, port in enumerate(ports): dev = tags[idx] pn = part_number_for(dev, rating_map) @@ -201,6 +204,7 @@ def write_sheet(ws, rows, title): ) yellow = PatternFill("solid", fgColor="FFC000") + red = PatternFill("solid", fgColor="FF0000") thin = Side(style="thin", color="000000") border = Border(left=thin, right=thin, top=thin, bottom=thin) center = Alignment(horizontal="center", vertical="center") @@ -218,11 +222,10 @@ def write_sheet(ws, rows, title): for dpm, group in groupby(rows, key=lambda x: x[0]): g = list(group) - # should already be 24 rows per DPM - g = g[:24] + num_rows = len(g) start = row_idx - end = row_idx + 24 - 1 + end = row_idx + num_rows - 1 ws.merge_cells(start_row=start, start_column=4, end_row=end, end_column=4) ws.merge_cells(start_row=start, start_column=5, end_row=end, end_column=5) @@ -235,17 +238,23 @@ def write_sheet(ws, rows, title): cell.border = border cell.font = Font(bold=False) - for i in range(24): + for i in range(num_rows): row_vals = { 6: g[i][2], # Assigned Device 7: g[i][3], # Part Number 8: g[i][4], # IP 9: g[i][5], # DPM PORT } + # Highlight rows beyond 24th device in red + is_overflow = i >= 24 + fill_color = red if is_overflow else None + for col, val in row_vals.items(): c = ws.cell(row=start + i, column=col, value=val) c.alignment = left if col in (6, 7, 9) else center c.border = border + if fill_color: + c.fill = fill_color for r in range(start + 1, end + 1): for col in (4, 5): diff --git a/AutoCAD/RenAttrib.LSP b/AutoCAD/RenAttrib.LSP new file mode 100644 index 0000000..13aa130 --- /dev/null +++ b/AutoCAD/RenAttrib.LSP @@ -0,0 +1,314 @@ +;;; Rename Attributes by Irné Barnard +;;; Version 3 + +(vl-load-com) + +(defun RenAtt:LoadSettings (filename / f s lst) + (if (and (or (setq f (findfile (cond (filename) + ("RenAttrib.DAT")))) + (setq f (findfile (strcat (getvar "RoamableRootPrefix") "RenAttrib.DAT")))) + (setq f (open f "r"))) + (progn + (setq lst "") + (while (setq s (read-line f)) (setq lst (strcat lst "\n" s))) + (setq lst (read lst)) + (close f))) + (setq *RenAtt:Settings* lst)) + +(RenAtt:LoadSettings nil) + +(defun RenAtt:SaveSettings (filename / f) + (setq f (cond (filename) + ((findfile "RenAttrib.DAT")) + ((strcat (getvar "RoamableRootPrefix") "RenAttrib.DAT")))) + (if (setq f (open f "w")) + (progn + (prin1 *RenAtt:Settings* f) + (close f)))) + +;; Get ALL (even duplicate) attributes from a block reference +(defun RenAtt:GetAttributes (obj / an ao lst) + (setq an (vlax-vla-object->ename obj)) + (while (and (setq an (entnext an)) + (setq ao (vlax-ename->vla-object an)) + (eq (vla-get-ObjectName ao) "AcDbAttribute")) + (setq lst (cons ao lst))) + lst) + +(defun RenAtt:GetBlocks (/ lst item name attList attTest attName changed) + (or *AcadApp* (setq *AcadApp* (vlax-get-acad-object))) + (or *ActiveDocument* (setq *ActiveDocument* (vla-get-ActiveDocument *AcadApp*))) + (or *BlocksCollection* (setq *BlocksCollection* (vla-get-Blocks *ActiveDocument*))) + ;; Get attributes from block definitions + (vlax-for blk *BlocksCollection* + (if (wcmatch (setq name (vla-get-Name blk)) "~`**") + (progn + (setq item nil) + (vlax-for obj blk + (if (eq (vla-get-ObjectName obj) "AcDbAttributeDefinition") + (if (setq attTest (assoc (setq attName (strcase (vla-get-TagString obj))) item)) + (setq item (subst (cons attName (1+ (cdr attTest))) attTest item)) + (setq item (cons (cons attName 1) item))))) + (if item + (setq lst (cons (cons (strcase name) (reverse item)) lst)))))) + ;; Get attributes from block references + (vlax-for blk *BlocksCollection* + (vlax-for obj blk + (if (and (eq (vla-get-ObjectName obj) "AcDbBlockReference") (eq (vla-get-HasAttributes obj) :vlax-true)) + (progn + (setq attList nil) + (foreach att (vlax-invoke obj "GetAttributes") + (if (and (setq attName (strcase (vla-get-TagString att))) (setq attTest (assoc attName attList))) + (setq attList (subst (cons attName (1+ (cdr attTest))) attTest attList)) + (setq attList (cons (cons attName 1) attList)))) + (setq name (strcase (vla-get-EffectiveName obj)) + item (reverse (cdr (assoc name lst))) + attName nil) + (foreach att (reverse attList) + (if (setq attTest (assoc (setq attName (car att)) item)) + (if (> (cdr att) (cdr attTest)) + (setq changed t + item (subst att attTest item))) + (setq changed t + item (cons att item)))) + ;; Merge into block definition list + (if changed + (setq lst (subst (cons name (reverse item)) (assoc name lst) lst))))))) + (reverse lst)) + +(defun RenAtt:MergeData (Settings NewData / old old2 attOld len) + (foreach item NewData + (if (setq old2 (setq old (assoc (car item) Settings))) + (foreach att (cdr item) + (if (setq attOld (assoc (car att) (cdr old))) + (if (> (cdr att) (setq len (1- (length attOld)))) + (setq Settings + (subst + (setq old (subst (append attOld (_MakeList (car att) (- (cdr att) len))) attOld old)) + old2 + Settings) + old2 old)) + ;;Some error here + (setq Settings (subst (append old (list (cons (car att) (_MakeList (car att) (cdr att))))) old Settings)))) + (setq Settings + (append + Settings + (list + (cons (car item) + (mapcar (function (lambda (attName) (list attName attName))) + (apply 'append (mapcar (function (lambda (a) (_MakeList (car a) (cdr a)))) (cdr item)))))))))) + Settings) + +(defun _MakeList (val count / lst) (repeat count (setq lst (cons val lst)))) +(defun _FirstN (lst num / res) + (if (< num (length lst)) + (progn + (repeat num + (setq res (cons (car lst) res) + lst (cdr lst))) + (reverse res)) + lst)) +(defun _CdrN (lst num /) (repeat num (setq lst (cdr lst)))) +(defun _ReplaceN (val idx lst /) + (if (< idx 0) + (cons val lst) + (append (_FirstN lst idx) (list val) (_CdrN lst (1+ idx))))) +(defun _RemoveN (lst idx /) + (if (< idx 0) + (cons val lst) + (append (_FirstN lst idx) (_CdrN lst (1+ idx))))) + +(defun RenAttr (obj / setting found) + (cond + ((and (eq (vla-get-ObjectName obj) "AcDbBlockReference") + (eq (vla-get-HasAttributes obj) :vlax-true) + (setq setting (assoc (strcase (vla-get-EffectiveName obj)) *RenAtt:Settings*))) + (setq setting (cdr setting)) + (foreach att (vlax-invoke obj "GetAttributes") + (if (setq found (assoc (strcase (vla-get-TagString att)) setting)) + (progn + (setq setting (_RemoveN setting (vl-position found setting))) + (if (not (eq (car found) (cadr found))) + (vla-put-TagString att (cadr found))))))) + ((and (eq (vla-get-ObjectName obj) "AcDbBlockTableRecord") + (setq setting (assoc (strcase (vla-get-Name obj)) *RenAtt:Settings*))) + (setq setting (cdr setting)) + (vlax-for att obj + (if (and (eq (vla-get-ObjectName att) "AcDbAttributeDefinition") + (setq found (assoc (strcase (vla-get-TagString att)) setting))) + (progn + (setq setting (_RemoveN setting (vl-position found setting))) + (if (not (eq (car found) (cadr found))) + (vla-put-TagString att (cadr found))))))))) + +(defun c:RenAttr (/) + (or *AcadApp* (setq *AcadApp* (vlax-get-acad-object))) + (or *ActiveDocument* (setq *ActiveDocument* (vla-get-ActiveDocument *AcadApp*))) + (or *BlocksCollection* (setq *BlocksCollection* (vla-get-Blocks *ActiveDocument*))) + ;; Get attributes from block definitions + (vlax-for blk *BlocksCollection* + (if (wcmatch (vla-get-Name blk) "~`**") + (RenAttr blk)) + (vlax-for obj blk (RenAttr obj))) + (princ)) + +(defun c:RenAttrSet (/ dcl s Blocks Settings ~btnCurrentAdd ~btnCurrentRem ~lstBlocks ~lstAttribs ~btnSave) + (if + (and (setq dcl (open (setq s (strcat (getvar "TempPrefix") "RenAttrib.DCL")) "w")) + (princ + (strcat + "RenAttrSet : dialog {\n" + " label = \"Rename Attributes - Settings\";\n" + " : row {\n" + " : boxed_column {\n" + " label = \"Blocks in current Drawing\";\n" + " : list_box { height = 20; key = \"lstCurrent\"; width = 30; multiple_select = true; }\n" + " : column {\n" + " : button { label = \"Add to Settings\"; key = \"btnCurrentAdd\"; }\n" + " : button { label = \"Remove from Settings\"; key = \"btnCurrentRem\"; }\n" + " }\n" + " }\n" + " : boxed_column {\n" + " label = \"Settings\";\n" + " :row { : column {\n" + " : list_box { label = \"Block Names\"; key = \"lstBlocks\"; width = 30; height = 20; }\n" + " : edit_box { label = \"New Name\"; key = \"edtName\"; edit_width = 25; }\n" + " }\n" + " : column {\n" + " : list_box { label = \"Old Attribute Names\"; key = \"lstAttribs\"; width = 30; height = 20; }\n" + " : retirement_button { key = \"btnSave\"; label = \" Save \"; }\n" + " }}\n" + " : row {\n" + " fixed_width = true;\n" + " alignment = centered;\n" + " : button { label = \"Clear\"; key = \"clear\"; action = \"(done_dialog 2)\"; }\n" + " : spacer { width = 2; }\n" + " ok_button;\n" + " : spacer { width = 2; }\n" + " cancel_button;\n" + " }\n" + " }\n" + " }\n" + "}") + dcl) + (not (close dcl)) + (setq dcl (load_dialog s)) + (new_dialog "RenAttrSet" dcl)) + (progn + ;; Action on button "Add to Settings" clicked + (defun ~btnCurrentAdd (/ idx) + (if (not (eq (setq idx (get_tile "lstCurrent")) "")) + (progn + (setq idx (mapcar (function (lambda (n) (nth n Blocks))) (read (strcat "(" idx ")"))) + Settings (RenAtt:MergeData Settings idx)) + (start_list "lstBlocks") + (mapcar 'add_list (mapcar 'car Settings)) + (end_list) + (set_tile "lstBlocks" "") + (~lstBlocks)))) + ;; Action on button "Add to Settings" clicked + (defun ~btnCurrentRem (/ idx) + (if (not (eq (setq idx (get_tile "lstCurrent")) "")) + (progn + (setq idx (mapcar (function (lambda (n) (nth n Blocks))) (read (strcat "(" idx ")")))) + (foreach i idx + (setq i (assoc (car i) Settings) + Settings (vl-remove i Settings))) + (start_list "lstBlocks") + (mapcar 'add_list (mapcar 'car Settings)) + (end_list) + (set_tile "lstBlocks" "") + (~lstBlocks)))) + ;; Action on selection "Block Names" changed + (defun ~lstBlocks (/ idx) + (if (not (eq (setq idx (get_tile "lstBlocks")) "")) + (progn + (start_list "lstAttribs") + (mapcar 'add_list + (mapcar + (function + (lambda (att) + (if (eq (car att) (cadr att)) + (car att) + (strcat (car att) " <" (cadr att) ">")))) + (cdr (nth (atoi idx) Settings)))) + (end_list) + (mode_tile "lstAttribs" 0) + (set_tile "lstAttribs" "")) + (progn + (start_list "lstAttribs") + (setq idxLst nil) + (end_list) + (mode_tile "lstAttribs" 1) + (set_tile "lstAttribs" ""))) + (~lstAttribs)) + + ;; Action on selection "Old Attribute Names" changed + (defun ~lstAttribs (/ idx1 idx2 blk att) + (if (and (not (eq (setq idx1 (get_tile "lstBlocks")) "")) + (not (eq (setq idx2 (get_tile "lstAttribs")) "")) + (setq blk (nth (atoi idx1) Settings)) + (setq att (nth (atoi idx2) (cdr blk)))) + (progn + (set_tile "edtName" (cadr att)) + (mode_tile "edtName" 0) + (mode_tile "btnSave" 0)) + (progn + (set_tile "edtName" "") + (mode_tile "edtName" 1) + (mode_tile "btnSave" 1)))) + + ;; Action on button "Save" clicked + (defun ~btnSave (/ idx1 idx2 blk att) + (if (and (not (eq (setq idx1 (get_tile "lstBlocks")) "")) + (not (eq (setq idx2 (get_tile "lstAttribs")) "")) + (setq idx1 (atoi idx1) + idx2 (atoi idx2)) + (setq blk (nth idx1 Settings)) + (setq att (nth idx2 (cdr blk)))) + (progn + (setq Settings + (subst (cons (car blk) + (_ReplaceN (list (car att) (strcase (get_tile "edtName"))) idx2 (cdr blk))) + blk + Settings)) + (~lstBlocks) + (set_tile "lstAttribs" (itoa idx2)) + (~lstAttribs)))) + + (start_list "lstCurrent") + (mapcar 'add_list (mapcar 'car (setq Blocks (RenAtt:GetBlocks)))) + (end_list) + (setq Settings *RenAtt:Settings*) + (start_list "lstBlocks") + (mapcar 'add_list (mapcar 'car Settings)) + (end_list) + (action_tile "btnCurrentAdd" "(~btnCurrentAdd)") + (action_tile "btnCurrentRem" "(~btnCurrentRem)") + (action_tile "lstBlocks" "(~lstBlocks)") + (action_tile "lstBlocks" "(~lstBlocks)") + (action_tile "lstAttribs" "(~lstAttribs)") + (action_tile "btnSave" "(~btnSave)") + (cond + ((= (setq s (start_dialog)) 1) + (setq *RenAtt:Settings* Settings) + (RenAtt:SaveSettings nil) + (unload_dialog dcl)) + ((= s 2) + (if (eq (progn (initget "Yes No") + (getkword "Are you sure you want to clear all block settings? [Yes/No] : ")) + "Yes") + (while (setq s (cond ((findfile "RenAttrib.DAT")) + ((findfile (strcat (getvar "RoamableRootPrefix") "RenAttrib.DAT"))))) + (vl-file-delete s))) + (unload_dialog dcl) + (c:RenAttrSet)) + (t (unload_dialog dcl))) + )) + (princ)) + + + + ;|«Visual LISP© Format Options» +(120 2 1 0 nil "end of " 100 9 0 0 0 nil T nil T) +;*** DO NOT add text below the comment! ***|;