diff --git a/clients/dataforth/.gitignore b/clients/dataforth/.gitignore new file mode 100644 index 0000000..52a34e5 --- /dev/null +++ b/clients/dataforth/.gitignore @@ -0,0 +1,3 @@ + +# plaintext credential note - never commit +Oauth.txt diff --git a/clients/dataforth/session-logs/2026-04-14-session.md b/clients/dataforth/session-logs/2026-04-14-session.md new file mode 100644 index 0000000..313d76f --- /dev/null +++ b/clients/dataforth/session-logs/2026-04-14-session.md @@ -0,0 +1,292 @@ +# Session Log — Dataforth — 2026-04-14 + +## DFWDS port + Hoffman API uploader pipeline (end-to-end working) + +Mid-day session: pulled the legacy DFWDS VB6 source from AD1, ported its file-classification logic to Node, wired up the bulk uploader against Hoffman's new `https://www.dataforth.com` API, drained the 897-file Test_Datasheets backlog, and pushed everything currently in For_Web to the live server. End result: server caught up to the AD2 For_Web state with 803 new records created. + +(Earlier today this same conversation also did a bunch of email-account password resets via ACG-DC16 — those are noted at the bottom for completeness but aren't Dataforth.) + +--- + +## Session Summary + +### What was accomplished + +1. **Pulled DFWDS source** (Dataforth Web Datasheet System, VB6) from AD1 via AD2 jump host. 71 files / 957 KB. Folder structure: `Program/`, `Release/` (current source: DFWDS.bas + frmSplash.frm + DFWDS.exe), `_Notes/` (developer docs), `_Working/` (WIP), plus `History/` snapshots from 2014-09-24 through 2014-10-02. + +2. **Determined what DFWDS actually does** (1181 lines of VB6): pure filesystem mover/renamer. Reads `X:\Test_Datasheets\*.txt`, validates filename, moves valid → `X:\For_Web`, bad → `X:\Bad_Datasheets`, logs to `X:\Datasheets_Log\DFWDS_YYYY_MM_DD.log`. **No HTTP/FTP code** — "website" in the name only refers to the destination folder; web upload was always a separate piece (currently the new Hoffman API). + +3. **Validation rules captured from VB source:** + - Filename must be `.txt` + - Must contain a dash; left-of-dash = Work Order # + - WO# is all-numeric → valid (unless starts with 0) + - WO# starts with `A`-`J` followed by digits → DOS-encoded; decode first char to a 2-digit prefix (`A`=10, `B`=11, ... `J`=19) and rename in place, then move to For_Web + - Anything else → bad + +4. **Probed the X: drive state on AD2** — `\\ad2\webshare\`: + - `Test_Datasheets`: 897 files, 2.4 MB, dates 2026-02-09 → 2026-04-13 14:42 (DFWDS hadn't run since 2026-03-11, ~33 days) + - `Bad_Datasheets`: 18,801 files (historical, oldest 2003) + - `For_Web`: 6,258 files at start of session (later 7,061 after DFWDS port ran) + - `Datasheets_Log`: 3,336 log files + +5. **Found existing reference scripts** in `projects/dataforth-dos/datasheet-pipeline/`: + - `test-upload-two.py` — single POST + roundtrip diff + - `test-scenarios.py` — idempotency, update, bulk tests (all green) + - `fetch-server-inventory.py` — paginates GET, writes serial list + - `compute-delta.py` — diffs local vs server inventories + - All four were prior work that proved the API contract end-to-end. Confirmed `dataforth.onprem.sync` client + `Trxvwee2234-Awer8723-2` secret + `dataforth.web` scope still works. + +6. **Read API Swagger** (`https://www.dataforth.com/swagger/v1/swagger.json`). Endpoints of interest: + - `GET /api/v1/TestReportDataFiles/stats` → TotalCount, LatestCreatedAtUtc, LatestUpdatedAtUtc + - `GET /api/v1/TestReportDataFiles?page=&pageSize=&afterSerialNumber=` → list (cursor-paginated) + - `GET /api/v1/TestReportDataFiles/{serialNumber}` → fetch one + - `POST /api/v1/TestReportDataFiles` body `{SerialNumber, Content}` → 200/201 + - `POST /api/v1/TestReportDataFiles/bulk` body `{Items: [{SerialNumber, Content}, ...]}` → returns TotalReceived/Created/Updated/Unchanged/Errors + - `DELETE /api/v1/TestReportDataFiles/{serialNumber}` + +7. **Discovered the 6,240-record delta from yesterday was already uploaded** by some earlier process (today ~13:44 server time). Server jumped 483,339 → 489,579 between yesterday's snapshot and the start of this session. Spot-checks on `100078-1`, `99693-9`, `51848-7` confirmed `CreatedAtUtc = 2026-04-14T13:44`. Our test-50 came back all `Unchanged` because the records were there already. + +8. **Wrote `dfwds-process.js`** — Node port of DFWDS's classification + move logic. ~120 lines. Mirrors VB validation exactly: ext check, dash position, all-numeric vs A-J prefix, decode + rename if prefixed. + +9. **Wrote `upload-delta.js`** — Node bulk uploader. Reads pipe-delimited delta file (`SN|path|size|mtime`), batches into POST `/bulk`, refreshes token before expiry (1h TTL), retries 401 once, logs every batch result. + +10. **Wrote orchestrators**: + - `run_uploader_on_ad2.py` — SFTP scripts to AD2, set CF_* env vars in encoded PowerShell command, run uploader + - `run_full_drain.py` — full pipeline: DFWDS → re-inventory → delta → upload (built but timed out at server-inventory pull step) + - `upload_all_for_web.py` — simpler: enumerate For_Web, push everything (idempotent server handles dedup) + +11. **End-to-end run of the pipeline:** + - Dry-run DFWDS on 897: classified all as `valid=897 renamed=0 bad=0` (modern serial-number format, no DOS prefixes in the queue) + - Live DFWDS run: 897/897 moved to For_Web in 1.1 seconds. For_Web: 6,258 → 7,061 (gain of 803, meaning ~94 of the 897 SNs already existed in For_Web and got overwritten in place) + - Skipped the slow full-server-inventory pull (was timing out at 10 min mark, ~400K of ~490K records) + - Just pushed entire For_Web to API: 7,061 items in 49.7s @ ~142/s sustained + - Result: **803 created, 114 updated, 6,144 unchanged, 0 errors** + - Server total: 489,579 → **490,382** (+803 new records) + - LatestCreatedAtUtc: `2026-04-15T03:58:00` + +### Key decisions & rationale + +- **Node, not Python, for the on-AD2 scripts.** Node is already installed on AD2 (used by testdatadb), no new runtime needed. Aligns with the testdatadb stack that the future DFWDS replacement should integrate into. +- **`.replace('\\','')` for the AD2 vault password** — same stale-shell-escape issue as before in `clients/dataforth/ad2.sops.yaml`. Vault entry still needs cleanup. +- **Skipped the slow inventory diff in the final run** — server is idempotent (returns Unchanged for matching content), so just pushing all of For_Web works. Full server inventory takes ~700s (490K records @ 700/s pagination). Not worth waiting when we can let the server tell us what's new. +- **Did NOT install Python on AD2** — user offered to ("install whatever is necessary") but Node was already there and the rewrite was clean. No improvement from adding a second runtime. +- **Used env vars (`CF_*`) for credentials in the on-AD2 invocation** — passed via SSH-encoded PowerShell, not written to disk. Credentials only live on the workstation in SOPS vault. +- **Two scripts on AD2 are reusable for ongoing automation:** `dfwds-process.js` and `upload-delta.js` are the two pieces that need to run nightly going forward. + +### Problems encountered and resolutions + +| Problem | Resolution | +|---|---| +| `\\ad2\` UNC path doesn't resolve from my workstation (DNS / SMB blocked over OpenVPN) | Deployed scripts to AD2 (`C:\Users\sysadmin\Documents\dataforth-uploader\`) and ran them locally with `node` | +| AD2 has no Python | Ported uploader from `upload-delta.py` to `upload-delta.js` (Node already installed) | +| `fetch-server-inventory.py` timed out at 600s after 405,918 of ~490K records | Skipped the full inventory; pushed all of For_Web directly and let server's idempotency dedup | +| First test-50 came back all `Unchanged` | Investigation revealed the original delta had already been uploaded earlier today (server count jumped 483,339 → 489,579 between yesterday's snapshot and now). Idempotency working as designed. | +| PowerShell regex to extract just the 897 from DFWDS log produced 0 matches | Pivoted to enumerate-everything-in-For_Web approach; idempotent server handles it just as well | +| `socket.timeout` on `https://www.dataforth.com` from workstation | Probably OpenVPN routing; retried with longer timeout, worked. Server itself is healthy. | + +--- + +## Credentials + +### Dataforth Product API (Hoffman) — already in vault +- Vault: `clients/dataforth/api-oauth.sops.yaml` +- Token URL: `https://login.dataforth.com/connect/token` +- API base: `https://www.dataforth.com` +- Swagger: `https://www.dataforth.com/swagger/v1/swagger.json` +- Grant type: `client_credentials` +- Client ID: `dataforth.onprem.sync` +- Client secret: `Trxvwee2234-Awer8723-2` +- Scope: `dataforth.web` +- TTL: 1 hour +- Token claim `role` = Admin + +### AD2 (Dataforth) +- SSH: `sysadmin / Paper123!@#` on 192.168.0.6:22 +- Vault entry stores `Paper123\!@#` (stale shell-escape; strip with `.replace('\\','')`) + +### ACG-DC16 (separate work, see "Email password resets" below) +- WinRM 5985: `administrator@acg.local / Gptf*77ttb##` on 172.16.3.50 + +--- + +## Infrastructure & Servers + +### AD2 webshare structure (verified today) +| Folder | Purpose | Files (start) | Files (end) | +|---|---|---|---| +| `\\ad2\webshare\Test_Datasheets` | DFWDS input staging | 897 | 0 (drained) | +| `\\ad2\webshare\Bad_Datasheets` | DFWDS quarantine | 18,801 | 18,801 (no bad in this batch) | +| `\\ad2\webshare\For_Web` | DFWDS output / API source | 6,258 | 7,061 | +| `\\ad2\webshare\Datasheets_Log` | DFWDS run logs | 3,336 | 3,337 (today's added) | + +### Hoffman API server state +- Start of session: `TotalCount=489,579`, `LatestCreatedAtUtc=2026-04-14T13:45:23` (from a backfill earlier today by someone/something else) +- End of session: `TotalCount=490,382` (+803), `LatestCreatedAtUtc=2026-04-15T03:58:00` + +### AD2 deployment dir (new) +- `C:\Users\sysadmin\Documents\dataforth-uploader\` + - `dfwds-process.js` + - `upload-delta.js` + - `delta_for_web_all.txt` (transient) + - `for_web_inventory.txt` (transient) + - `delta_to_upload.txt` (transient, from yesterday's compute-delta) + - `upload-logs/` (per-run timestamped logs) + +--- + +## Commands & Outputs + +### Final upload-delta.js run (the headline result) +``` +[INFO] 7061 items queued (start=0 limit=all batch=100) +[OK] token len=915 + batch 1/71: recv=100 cre=0 upd=2 unch=98 err=0 | rate=37/s + ... + batch 71/71: recv=61 cre=0 upd=0 unch=61 err=0 | rate=142/s + +[DONE] elapsed 49.7s + received: 7061 + created: 803 + updated: 114 + unchanged: 6144 + errors: 0 +``` + +### DFWDS port live run +``` +[2026-04-15T03:44:00.797Z] === DFWDS-process start (Node port) === + in: C:\Shares\webshare\Test_Datasheets + out: C:\Shares\webshare\For_Web + bad: C:\Shares\webshare\Bad_Datasheets + dry: false, limit: all + queued: 897 files (of 897 in dir) + ... + === summary: valid=897 renamed=0 bad=0 errors=0 +[INFO] log: C:\Shares\webshare\Datasheets_Log\DFWDS_2026_04_14.log +``` + +### Quick OAuth token grab (handy CLI) +```bash +curl -sS -X POST https://login.dataforth.com/connect/token \ + -d grant_type=client_credentials \ + -d client_id=dataforth.onprem.sync \ + -d client_secret=Trxvwee2234-Awer8723-2 \ + -d scope=dataforth.web +``` + +--- + +## Configuration Changes + +### New files created (all in `D:\claudetools\projects\dataforth-dos\`) + +| Path | Lines | Purpose | +|---|---|---| +| `dfwds-research/probe_dfwds.py` | ~30 | Initial AD1 folder probe | +| `dfwds-research/fetch_dfwds.py` | ~70 | Pulls full DFWDS tree to local via AD2 stage + SFTP | +| `dfwds-research/check_x_drive.py` | ~50 | Inventories X: folders to see DFWDS workload | +| `dfwds-research/api_probe.py` | ~50 | OAuth + Swagger fetch + endpoint listing | +| `dfwds-research/source/` | 72 files | Pulled DFWDS tree (Program/, Release/, _Notes/, _Working/, History/) | +| `dfwds-research/swagger.json` | (full Swagger dump) | For offline reading | +| `datasheet-pipeline/dfwds-process.js` | ~120 | Node port of DFWDS classification + move | +| `datasheet-pipeline/upload-delta.js` | ~190 | Node bulk uploader to Hoffman API | +| `datasheet-pipeline/probe_ad2_runtime.py` | ~15 | Check Python/Node availability on AD2 | +| `datasheet-pipeline/run_uploader_on_ad2.py` | ~80 | Orchestrator: SFTP + run uploader | +| `datasheet-pipeline/run_full_drain.py` | ~110 | Orchestrator: DFWDS + inventory + delta + upload | +| `datasheet-pipeline/upload_all_for_web.py` | ~70 | Simpler orchestrator: enumerate + push everything | +| `datasheet-pipeline/upload_897.py` | ~80 | (Failed regex experiment — can delete) | + +### Files changed on AD2 +- New: `C:\Users\sysadmin\Documents\dataforth-uploader\dfwds-process.js` +- New: `C:\Users\sysadmin\Documents\dataforth-uploader\upload-delta.js` +- 897 files moved: `C:\Shares\webshare\Test_Datasheets\*.txt` → `C:\Shares\webshare\For_Web\*.txt` +- New log file: `C:\Shares\webshare\Datasheets_Log\DFWDS_2026_04_14.log` + +### Local machine +- Python `pyyaml` — already installed (used for SOPS YAML parsing) +- Python `paramiko` 4.0.0 — already installed + +--- + +## Pending / Incomplete / Open Items + +1. **Wire up scheduled automation on AD2.** Currently this whole pipeline runs only when triggered manually from the workstation. Need either: + - (a) `creds.json` on AD2 (ACL'd to SYSTEM/svc_testdatadb) + Windows Scheduled Task running `dfwds-process.js` then `upload-delta.js` nightly + - (b) Workstation cron → SSH to AD2 → run with env-var creds + - (c) Windows Credential Manager on AD2 + + User asked which to wire (a or b) at end of session — **awaiting decision.** + +2. **Integrate into the testdatadb pipeline.** The current scripts run separately from `C:\Shares\testdatadb`. Cleaner integration would have `database/import.js` trigger DFWDS-process + upload after each incremental import, rather than nightly batch. + +3. **Vault hygiene** (carryover from previous sessions): + - `clients/dataforth/ad2.sops.yaml` has stale `\!` escape in password (workaround in code: `.replace('\\','')`) + - Cloudflare tokens still in 1Password only, not in `services/cloudflare.sops.yaml` + +4. **Re-run server inventory** at some point so we have a fresh baseline. Today's pull timed out at 405K. The data isn't critical for ongoing operation since we use the server's idempotency, but having a fresh `server_inventory.txt` makes future delta computations faster than re-uploading everything. + +5. **Delete `upload_897.py`** (failed regex experiment) — superseded by `upload_all_for_web.py`. + +--- + +## Reference Information + +### URLs / endpoints +- Swagger UI: `https://www.dataforth.com/swagger/index.html` +- Identity Server: `https://login.dataforth.com` +- OIDC discovery: `https://login.dataforth.com/.well-known/openid-configuration` + +### File paths (will need again) +- AD2 deployment dir: `C:\Users\sysadmin\Documents\dataforth-uploader\` +- AD2 webshare: `C:\Shares\webshare\` (Test_Datasheets, For_Web, Bad_Datasheets, Datasheets_Log) +- AD1 DFWDS source: `\\AD1\Engineering\ENGR\ATE\Test Datasheets\DFWDS\` +- Local workspace: `D:\claudetools\projects\dataforth-dos\` +- Local DFWDS source pull: `D:\claudetools\projects\dataforth-dos\dfwds-research\source\` +- Local pipeline scripts: `D:\claudetools\projects\dataforth-dos\datasheet-pipeline\` + +### DFWDS classification rules (one-liner reference) +- `.txt` extension required +- Dash required in stem; left-of-dash = WO# +- WO# all-numeric → valid (unless leading 0) +- WO# `[A-J]\d+` → decode first char (A=10, B=11, ... J=19), rename file in place, then move +- Anything else → bad + +### API behavior notes +- `POST /bulk`: server returns counts per category in single response. `Updated` = same SN, different content. `Unchanged` = same SN, same content. `Created` = new SN. +- Token TTL = 3600s. Uploader refreshes 60s before expiry. +- Server pagination: `?page=N&pageSize=1000&afterSerialNumber=`. Page sizes up to 1000 work. + +### Sustained throughput observed today +- Bulk upload: ~142 files/s sustained for ~50s (batches of 100, single client) +- Server inventory pagination: ~700 records/s + +--- + +## Other work in this same conversation (non-Dataforth) + +Earlier today this session also handled email-account password resets on **ACG-DC16** (acg.local domain, 172.16.3.50) for accounts hosted by Neptune Exchange. Captured here for completeness — full detail is independent of Dataforth: + +| Account | Email | New password | +|---|---|---| +| `cansley_starrpass.c` | cansley@devconllc.com (Chris Ansley) | `Natascha8144$` | +| `bertie2` | bertie@amtransit.com (Ana Lozano) | `2026@Arizona` | +| `caitlin` | caitlin@amtransit.com | `Welcomeamt2026!` | +| `matilde` | matilde@amtransit.com (Slate) | `Welcomeamt2026!` | +| `nydia` | Nydia@amtransit.com | `Welcomeamt2026!` | +| `tom` | tsorensen@RieussetCorp.com (Tom Sorensen) | `RC$sor3740` | +| `tomrc` | tomrc@RieussetCorp.com (Tom Sorensen) | `RC$sor3740` | +| `ojodeagua` | ojodeagua@RieussetCorp.com (Tom Sorensen) | `RC$sor3740` | +| `csorensen` | csorensen@RieussetCorp.com (Christine Sorensen) | `RC$sor3740` | + +Untouched intentionally: `driver@amtransit.com`, `Jeffrey.Schaufel` (request cancelled). + +Method: Python `winrm` with auth `administrator@acg.local / Gptf*77ttb##`, `Set-ADAccountPassword -Reset` + `Unlock-ADAccount`. UPN format required (`ACG\administrator` failed initial Python NTLM auth due to escape sequence quirk). + +Also today: created the **IMC ticket-notes write-up** at `clients/instrumental-music-center/docs/2026-04-13-ticket-notes.md` (formatted 2026-04-11/12/13 IMC1 work for the PSA ticket — RDS removal blocked, SQL backup cleanup, DB relocation, RDS removal parked). Opened in Notepad++ for the user. + +Also: **Cloudflare DNS cleanup** — flipped `unifi.azcomputerguru.com` was already grey-cloud (no-op); flagged `ui.azcomputerguru.com` as the more likely target (still proxied + 525) — user didn't act on that. + +--- + +**Last Updated:** 2026-04-14 21:00 +**Next Actions:** decide automation approach (a/b/c above), then commit + push. diff --git a/clients/instrumental-music-center/docs/2026-04-13-ticket-notes.md b/clients/instrumental-music-center/docs/2026-04-13-ticket-notes.md new file mode 100644 index 0000000..738cc88 --- /dev/null +++ b/clients/instrumental-music-center/docs/2026-04-13-ticket-notes.md @@ -0,0 +1,122 @@ +# IMC1 Maintenance — Ticket Notes (2026-04-11 through 2026-04-13) + +**Client:** Instrumental Music Center (IMC) +**Server:** IMC1 (Windows Server 2016, AD DC + AIMsi SQL host + RDS), 192.168.0.2 +**Dates worked:** Saturday 2026-04-11, Sunday 2026-04-12, finalized Monday 2026-04-13 + +--- + +## Original request + +Remove RDS role from IMC1 in preparation for a planned Server 2019 upgrade. + +## Outcome (short version) + +RDS role **could not be removed** — blocked by an underlying Windows component-store corruption that also affects Cumulative Update apply-on-boot. The 2019 upgrade path has to be reconsidered. + +Parallel/opportunistic work completed while diagnosing: **716 GB recovered on E:** (stale SQL backup cleanup), **GFS retention automated**, **AIMsi databases moved to dedicated SSD (S:)**, **out-of-band SSH access set up** for future work. + +--- + +## Work performed — billable + +### 1. Remote-access groundwork +- Installed OpenSSH Server on IMC1 from official GitHub release (Windows built-in `Add-WindowsCapability` install was a ghost — binaries never landed, also a symptom of the component-store corruption) +- Registered `sshd` + `ssh-agent` services, opened TCP/22 in the firewall +- Configured key-based auth (ed25519) via `C:\ProgramData\ssh\administrators_authorized_keys` with proper ACLs +- Set PowerShell as default SSH shell +- Identified & documented a routing conflict: Tailscale's `pfsense-2` subnet-router was advertising `192.168.0.0/24` with lower metric than the OpenVPN tunnel, making IMC1 unreachable via VPN. Workaround: disconnect Tailscale when using IMC OpenVPN. + +### 2. SQL backup cleanup — 716 GB freed on E: +- Inventoried `E:\SQL\MSSQL14.SQLEXPRESS\MSSQL\Backup\`: **66 nightly full backups, 905 GB total**, covering 2026-02-01 through 2026-04-11 +- Verified the off-site Cloudberry/MSP360 backup was intact before deleting locally +- Applied GFS retention manually: kept 14 dailies + 1st-of-month (16 files, 189 GB); deleted the other 50 (716 GB) +- Noted the per-backup size dropping from ~15 GB to ~11 GB around 2026-03-28 (someone archived or cleaned source data that day; unrelated to this work) + +### 3. Automated backup retention — going forward +- Wrote `C:\Scripts\Clean-AimsiBackups.ps1` implementing the same GFS policy (14 dailies + monthlies on day-1) +- Hard safety guards: minimum of 3 newest files always kept, filename-pattern validation, per-run logs to `C:\Scripts\Logs\aimsi-retention-YYYYMM.log` +- Registered Windows Scheduled Task `IMC AIMsi Backup Retention`: runs daily 23:30 as SYSTEM, 1-hour execution limit +- Test run completed successfully; script will keep backup footprint stable automatically from now on + +### 4. AIMsi SQL database relocation (C: → S:) +- Elevated `IMC\guru` to sysadmin on the `AIMSQL` instance via single-user-mode recovery (only Windows admins had sysadmin by default; `IMC\guru` wasn't in that group historically) +- Moved the three user databases from `C:` to the dedicated Samsung 850 PRO SSD (`S:\SQL\Data\`): + - `AIM.mdf` — 8.6 GB — production AIMsi database + - `IMC.mdf` — 9.8 GB — legacy (usage unclear; kept for safety) + - `TestConv61223.mdf` — 8.8 GB — leftover from a 2023-06-12 migration test; candidate for drop +- Moved `tempdb` + cleaned up its orphaned files on C: +- Left system DBs (`master`, `model`, `msdb`) on C: — moving `master` requires modifying SQL Server startup parameters and the benefit is marginal vs risk +- Verified AIM client launch after the move; 4 typical concurrent users connected fine +- **Disk impact:** `C:` 322 → 278 GB used (−44 GB); `S:` 27 → 53 GB used (+26 GB) + +### 5. RDS removal (parked — deeper than scoped) +Root error during `Uninstall-WindowsFeature RDS-RD-Server`: `0x80073701 ERROR_SXS_ASSEMBLY_MISSING`. + +Things we tried (in order): +1. `DISM /Online /Cleanup-Image /RestoreHealth` → failed Error 14 (internally `E_OUTOFMEMORY 0x8007000e` from an oversized 168 MB `COMPONENTS` registry hive — normal is 30–50 MB) +2. Same with explicit `/ScratchDir` → failed `E_ACCESSDENIED` because BITS + `wuauserv` were stopped +3. Started BITS/wuauserv and retried → BITS idles-and-auto-stops on Server 2016; DISM still couldn't fetch payloads +4. `/Source:WIM:E:\W2016\sources\install.wim:2 /LimitAccess` (install media on E:) → failed `CBS_E_SOURCE_MISSING`. The E:\W2016 image is RTM (14393.0); the damaged assembly is from a post-RTM Cumulative Update, so the RTM source doesn't have the right version +5. Extracted KB5075999 (Feb 2026 CU) from a local MSU and ran `DISM /Online /Add-Package` → **staged successfully (S_OK)**, but on reboot the apply phase failed with `HRESULT_FROM_WIN32(15010) ERROR_EVT_INVALID_EVENT_DATA` at `onecore\admin\wmi\events\config\manproc.cpp:733` — the ETW event manifest for provider GUID `{9c2a37f3-e5fd-5cae-bcd1-43dafeee1ff0}` is malformed → `CBS_E_INSTALLERS_FAILED` → full rollback + +**Decision:** parked. The component-store corruption is isolated (server otherwise healthy) but it prevents both RDS removal AND CU application. It's deeper than the originally scoped RDS-removal work, and needs a planning conversation before committing more time. + +### 6. Minor housekeeping +- Re-created the missing `C:\Users\guru\Downloads` folder (registry pointed there, the folder itself was gone) + +--- + +## Current state of IMC1 + +| Area | State | +|---|---| +| AIMsi production | healthy, clients connecting | +| SQL instance | running; user DBs on S:, system DBs on C: | +| SQL backups | retained by scheduled script; 189 GB footprint (vs prior 905 GB) | +| C: drive | 278/419 GB used (~66%) — comfortable | +| S: drive | 53/238 GB used | +| RDS role | still installed (removal blocked) | +| OS updates | latest successful CU prior to this session; KB5075999 rolled back | +| SSH access | working, key-based, admin group | + +--- + +## Open items / recommendations (for the next conversation) + +**Decision needed on the Server 2019 upgrade path.** Three realistic options: + +| Path | Rough effort | Notes | +|---|---|---| +| **A. Repair the component store, then retry RDS removal + in-place 2019 upgrade** | 2–4 hours, uncertain | Next step is to identify which KB owns the malformed provider GUID `{9c2a37f3-e5fd-5cae-bcd1-43dafeee1ff0}`, re-register its manifest via `wevtutil im`, retry. If the hive is just too damaged, this path fails the same way. | +| **B. In-place Server 2019 upgrade without fixing the corruption** | 2–3 hours attempt; high rollback risk | Microsoft's in-place upgrade rewrites system files wholesale; in practice it often resolves corruptions like this one, but if the upgrade itself encounters the same provider-manifest issue, we're worse off. | +| **C. Clean Server 2019 build + AD / SQL / file share / RDS migration** | 6–10 hours | Lowest risk of mid-flight breakage. Most predictable. Requires a cutover window. This is what I'd recommend if the upgrade is planned anyway. | + +**Also pending (independent of the upgrade):** +- Verify the `IMC` database (9.8 GB) is actively being used; drop if not +- Drop `TestConv61223` (8.8 GB leftover from 2023-06-12 migration test) once confirmed unused +- Disable SMB1: `Set-SmbServerConfiguration -EnableSMB1Protocol $false` (currently enabled — security hygiene) +- `IMC2`, `IMC-VM` in AD — last-logon 2023 and 2021 respectively, likely decommissioned; clean up if confirmed +- `SERVERIMC` (192.168.0.63) — its role/status is unclear from AD, worth verifying what it's doing + +--- + +## Key paths and references (for the next tech) + +- SSH: `ssh IMC\guru@192.168.0.2` (ed25519 key, PowerShell shell) +- Authorized keys file: `C:\ProgramData\ssh\administrators_authorized_keys` +- Retention script: `C:\Scripts\Clean-AimsiBackups.ps1` +- Retention logs: `C:\Scripts\Logs\aimsi-retention-YYYYMM.log` +- Scheduled task: `IMC AIMsi Backup Retention` (daily 23:30, SYSTEM) +- SQL instance: `IMC1\AIMSQL` (MSSQL15 = SQL Server 2019 Express, despite folder name) +- SQL data: `S:\SQL\Data\` (user DBs); `C:\Program Files\Microsoft SQL Server\MSSQL15.AIMSQL\MSSQL\DATA\` (system DBs) +- SQL backups: `E:\SQL\MSSQL14.SQLEXPRESS\MSSQL\Backup\` (yes, MSSQL14 folder hosting a MSSQL15 instance's backups — legacy) +- DISM scratch + extracted KB payload: `C:\DISMScratch\` +- Server 2016 install media (RTM): `E:\W2016\sources\install.wim` +- Full session log: `clients/instrumental-music-center/session-logs/2026-04-12-imc1-cleanup-and-sql-move.md` + +## Credentials + +- Domain admin + AIMSQL sysadmin: `IMC\guru` (password handled verbally, not stored in this file) +- Local admin + SSH: same account +- `sa` on AIMSQL: exists and enabled; password unknown (tried one candidate, wrong, no lockout triggered) diff --git a/projects/dataforth-dos/datasheet-pipeline/compute-delta.py b/projects/dataforth-dos/datasheet-pipeline/compute-delta.py new file mode 100644 index 0000000..0d667fb --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/compute-delta.py @@ -0,0 +1,74 @@ +"""Compare local For_Web serials vs server-side serials; emit delta list.""" +import os + +LOCAL = r"C:\Users\guru\AppData\Local\Temp\for_web_inventory.txt" +SERVER = r"C:\Users\guru\AppData\Local\Temp\server_inventory.txt" +DELTA_OUT = r"C:\Users\guru\AppData\Local\Temp\delta_to_upload.txt" + +# Load server set (case-sensitive exact; mirror what we'd POST as SerialNumber) +server = set() +with open(SERVER) as f: + for line in f: + s = line.strip() + if s: + server.add(s) + +# Also load a case-insensitive lookup just to see if anything only differs by case +server_ci = {s.lower() for s in server} + +# Walk local inventory +local_total = 0 +local_sns = set() +path_by_sn = {} +with open(LOCAL) as f: + for line in f: + parts = line.rstrip("\n").split("|") + if len(parts) < 4: + continue + full, sn, size, mtime = parts[0], parts[1], parts[2], parts[3] + local_total += 1 + local_sns.add(sn) + path_by_sn[sn] = (full, int(size), mtime) + +# Diff +missing_on_server = sorted(sn for sn in local_sns if sn not in server) +missing_ci_only = sorted(sn for sn in local_sns if sn not in server and sn.lower() in server_ci) +already_present = sorted(sn for sn in local_sns if sn in server) + +print(f"Local total: {local_total}") +print(f"Local unique serials: {len(local_sns)}") +print(f"Server total: {len(server)}") +print(f"") +print(f"Already on server (case-sensitive exact match): {len(already_present)}") +print(f"Missing on server (case-sensitive): {len(missing_on_server)}") +print(f" ...of which only differ by case: {len(missing_ci_only)}") +print(f"") + +# Write delta list (paths) to upload +with open(DELTA_OUT, "w") as f: + for sn in missing_on_server: + full, size, mtime = path_by_sn[sn] + f.write(f"{sn}|{full}|{size}|{mtime}\n") + +print(f"Wrote delta list ({len(missing_on_server)} entries) -> {DELTA_OUT}") + +# Show sample of delta +if missing_on_server: + print("\nFirst 10 missing SNs:") + for sn in missing_on_server[:10]: + full, size, mtime = path_by_sn[sn] + print(f" {sn} ({size} bytes, {mtime[:19]})") + print("\nLast 10 missing SNs:") + for sn in missing_on_server[-10:]: + full, size, mtime = path_by_sn[sn] + print(f" {sn} ({size} bytes, {mtime[:19]})") + +# Show counts by year-month for the delta +from collections import Counter +by_month = Counter() +for sn in missing_on_server: + _, _, mtime = path_by_sn[sn] + by_month[mtime[:7]] += 1 +print("\nDelta by year-month:") +for k in sorted(by_month): + print(f" {k}: {by_month[k]}") diff --git a/projects/dataforth-dos/datasheet-pipeline/dfwds-process.js b/projects/dataforth-dos/datasheet-pipeline/dfwds-process.js new file mode 100644 index 0000000..dfc1202 --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/dfwds-process.js @@ -0,0 +1,136 @@ +/** + * DFWDS-equivalent in Node — moves test datasheets from staging to For_Web, + * decodes any DOS A-J prefix on filenames, quarantines invalid files. + * + * Mirrors the validation logic from the original VB6 DFWDS.bas: + * - filename must be .txt + * - must contain a dash + * - work-order portion (left of dash) must be all-numeric and not start with 0 + * - OR the first char is A-J (DOS-encoded), which decodes to 10-19 and renames + * + * Defaults match the original DFWDS_NAMES.txt: + * --in \\ad2\webshare\Test_Datasheets + * --bad \\ad2\webshare\Bad_Datasheets + * --out \\ad2\webshare\For_Web + * --log \\ad2\webshare\Datasheets_Log + * + * Use --dry-run to see what would happen without moving anything. + */ +const fs = require('fs'); +const path = require('path'); + +const args = process.argv.slice(2); +const arg = (n, d) => { const i = args.indexOf(n); return i >= 0 ? args[i+1] : d; }; +const flag = (n) => args.includes(n); + +const IN_DIR = arg('--in', String.raw`C:\Shares\webshare\Test_Datasheets`); +const BAD_DIR = arg('--bad', String.raw`C:\Shares\webshare\Bad_Datasheets`); +const OUT_DIR = arg('--out', String.raw`C:\Shares\webshare\For_Web`); +const LOG_DIR = arg('--log', String.raw`C:\Shares\webshare\Datasheets_Log`); +const DRY = flag('--dry-run'); +const LIMIT = parseInt(arg('--limit', '0'), 10); + +// Per VB funcDecodeWOchar: A-J map to 10..19 (one char -> two digits) +const PREFIX_DECODE = { + A: '10', B: '11', C: '12', D: '13', E: '14', + F: '15', G: '16', H: '17', I: '18', J: '19', +}; + +function classify(filename) { + // Returns: {action: 'valid'|'rename'|'bad', newName?: string, reason?: string} + if (!filename.toLowerCase().endsWith('.txt')) { + return {action:'bad', reason:'not .txt'}; + } + const stem = filename.slice(0, -4); // strip .txt + const dash = stem.indexOf('-'); + if (dash <= 0) return {action:'bad', reason:'no dash or dash at start'}; + + const wo = stem.slice(0, dash).toUpperCase(); + const tail = stem.slice(dash); // includes leading '-' + + if (/^\d+$/.test(wo)) { + if (wo.startsWith('0')) return {action:'bad', reason:'WO starts with 0'}; + return {action:'valid'}; + } + + // Check DOS-encoded: first char A-J, rest all numeric + const first = wo[0]; + if (PREFIX_DECODE[first] && /^\d+$/.test(wo.slice(1))) { + const newWo = PREFIX_DECODE[first] + wo.slice(1); + return {action:'rename', newName: newWo + tail + '.txt'}; + } + + return {action:'bad', reason:`WO "${wo}" not numeric and not A-J prefixed`}; +} + +function ensureDir(d) { fs.mkdirSync(d, {recursive: true}); } + +function moveFile(src, dst) { + ensureDir(path.dirname(dst)); + if (fs.existsSync(dst)) { + // overwrite by removing first; rename in same dir is fine but cross-dir on Win sometimes errors if exists + fs.unlinkSync(dst); + } + fs.renameSync(src, dst); +} + +function main() { + if (!fs.existsSync(IN_DIR)) { + console.error(`[FAIL] input dir not found: ${IN_DIR}`); + process.exit(1); + } + ensureDir(BAD_DIR); ensureDir(OUT_DIR); ensureDir(LOG_DIR); + + // Log filename matches DFWDS pattern: DFWDS_YYYY_MM_DD.log + const now = new Date(); + const ymd = `${now.getFullYear()}_${String(now.getMonth()+1).padStart(2,'0')}_${String(now.getDate()).padStart(2,'0')}`; + const logPath = path.join(LOG_DIR, `DFWDS_${ymd}.log`); + const logFh = fs.openSync(logPath, 'a'); + function log(msg) { + const line = `[${new Date().toISOString()}] ${msg}\n`; + process.stdout.write(line); + fs.writeSync(logFh, line); + } + + log(`=== DFWDS-process start (Node port) ===`); + log(` in: ${IN_DIR}`); + log(` out: ${OUT_DIR}`); + log(` bad: ${BAD_DIR}`); + log(` dry: ${DRY}, limit: ${LIMIT||'all'}`); + + const all = fs.readdirSync(IN_DIR).filter(n => fs.statSync(path.join(IN_DIR, n)).isFile()); + const queue = LIMIT ? all.slice(0, LIMIT) : all; + log(` queued: ${queue.length} files (of ${all.length} in dir)`); + + const stats = {valid:0, renamed:0, bad:0, errors:0}; + for (const name of queue) { + const src = path.join(IN_DIR, name); + const cls = classify(name); + try { + if (cls.action === 'valid') { + const dst = path.join(OUT_DIR, name); + if (DRY) log(` [DRY VALID] ${name} -> ${dst}`); + else { moveFile(src, dst); log(` VALID ${name}`); } + stats.valid++; + } else if (cls.action === 'rename') { + const dst = path.join(OUT_DIR, cls.newName); + if (DRY) log(` [DRY RENAME] ${name} -> ${cls.newName} -> ${dst}`); + else { moveFile(src, dst); log(` RENAMED ${name} -> ${cls.newName}`); } + stats.renamed++; + } else { + const dst = path.join(BAD_DIR, name); + if (DRY) log(` [DRY BAD] ${name} (${cls.reason}) -> ${dst}`); + else { moveFile(src, dst); log(` BAD ${name} (${cls.reason})`); } + stats.bad++; + } + } catch (e) { + log(` ERR ${name}: ${e.message}`); + stats.errors++; + } + } + log(`=== summary: valid=${stats.valid} renamed=${stats.renamed} bad=${stats.bad} errors=${stats.errors}`); + fs.closeSync(logFh); + console.log(`\n[INFO] log: ${logPath}`); +} + +main(); diff --git a/projects/dataforth-dos/datasheet-pipeline/fetch-server-inventory.py b/projects/dataforth-dos/datasheet-pipeline/fetch-server-inventory.py new file mode 100644 index 0000000..2a3fb3c --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/fetch-server-inventory.py @@ -0,0 +1,80 @@ +"""Paginate API to fetch every server-side SerialNumber, write to file.""" +import json +import time +import urllib.request +import urllib.parse + +import os, sys +TOKEN_URL = os.environ.get("CF_TOKEN_URL", "https://login.dataforth.com/connect/token") +API_BASE = os.environ.get("CF_API_BASE", "https://www.dataforth.com") + "/api/v1" +CLIENT_ID = os.environ.get("CF_CLIENT_ID", "") +CLIENT_SECRET = os.environ.get("CF_CLIENT_SECRET", "") +SCOPE = os.environ.get("CF_SCOPE", "dataforth.web") +if not CLIENT_ID or not CLIENT_SECRET: + sys.exit("set CF_CLIENT_ID + CF_CLIENT_SECRET (vault: clients/dataforth/api-oauth.sops.yaml)") + +OUTFILE = r"C:\Users\guru\AppData\Local\Temp\server_inventory.txt" +PAGE_SIZE = 1000 # try 1000 first; smaller if server complains + + +def get_token(): + data = urllib.parse.urlencode({ + "grant_type": "client_credentials", + "client_id": CLIENT_ID, + "client_secret": CLIENT_SECRET, + "scope": SCOPE, + }).encode() + with urllib.request.urlopen(urllib.request.Request(TOKEN_URL, data=data)) as r: + return json.loads(r.read())["access_token"] + + +def main(): + token = get_token() + headers = {"Authorization": f"Bearer {token}"} + + total = 0 + page = 1 + cursor = None + t_start = time.time() + + with open(OUTFILE, "w") as f: + while True: + params = {"page": page, "pageSize": PAGE_SIZE} + if cursor: + params["afterSerialNumber"] = cursor + url = f"{API_BASE}/TestReportDataFiles?" + urllib.parse.urlencode(params) + req = urllib.request.Request(url, headers=headers) + try: + with urllib.request.urlopen(req, timeout=30) as r: + obj = json.loads(r.read()) + except Exception as e: + print(f" ERROR at page {page}: {e}") + # Refresh token and retry once + token = get_token() + headers = {"Authorization": f"Bearer {token}"} + with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=30) as r: + obj = json.loads(r.read()) + + items = obj.get("Items", []) + if not items: + break + + for it in items: + f.write(it["SerialNumber"] + "\n") + total += len(items) + cursor = obj.get("NextCursor") + + if page % 50 == 0 or page == 1: + rate = total / max(1, time.time() - t_start) + print(f" page {page}: total={total} rate={rate:.0f}/s cursor={cursor!r}") + + if not cursor: + break + page += 1 + + elapsed = time.time() - t_start + print(f"\nDONE: {total} serials written to {OUTFILE} in {elapsed:.1f}s") + + +if __name__ == "__main__": + main() diff --git a/projects/dataforth-dos/datasheet-pipeline/probe_ad2_runtime.py b/projects/dataforth-dos/datasheet-pipeline/probe_ad2_runtime.py new file mode 100644 index 0000000..bb03b48 --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/probe_ad2_runtime.py @@ -0,0 +1,14 @@ +"""Check AD2 for Python/Node availability.""" +import paramiko, subprocess, yaml +pwd_raw = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout)['credentials']['password'] +PWD = pwd_raw.replace('\\', '') +c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=PWD, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) +for cmd in ['where python', 'where python3', 'where node', 'python --version 2>&1']: + print(f'$ {cmd}') + _, o, _ = c.exec_command(cmd, timeout=15) + print(o.read().decode().rstrip()) + print() +c.close() diff --git a/projects/dataforth-dos/datasheet-pipeline/run_full_drain.py b/projects/dataforth-dos/datasheet-pipeline/run_full_drain.py new file mode 100644 index 0000000..dac7c8f --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/run_full_drain.py @@ -0,0 +1,121 @@ +"""Drain Test_Datasheets through DFWDS-Node, refresh inventory+delta, push to API. + +Steps: + 1. SFTP dfwds-process.js + fetch-server-inventory.js + compute-delta logic + (we'll use the existing Python ones for inventory; keep upload-delta.js as-is) + 2. Run DFWDS dry-run on AD2 to see what 897 would do + 3. Run DFWDS for real + 4. Re-build for_web inventory on AD2 (PowerShell one-liner) + 5. SFTP for_web inventory back, fetch server inventory locally, compute delta locally + 6. SFTP delta to AD2, run upload-delta.js +""" +import base64, paramiko, subprocess, sys, time, yaml, os, threading + +LIMIT = 0 # 0 = all 897 +DRY = False +for i, a in enumerate(sys.argv[1:]): + if a == '--limit': LIMIT = int(sys.argv[i+2]) + if a == '--dry-run': DRY = True + +ad2_pwd = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout)['credentials']['password'].replace('\\','') +api = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/api-oauth.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout) + +REMOTE_DIR = 'C:/Users/sysadmin/Documents/dataforth-uploader' +LOCAL = r'D:\claudetools\projects\dataforth-dos\datasheet-pipeline' +TEMP_DIR = r'C:\Users\guru\AppData\Local\Temp' + +c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=ad2_pwd, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) + +def run(cmd, to=300): + enc = base64.b64encode(cmd.encode('utf-16-le')).decode() + _, o, _ = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to) + return o.read().decode('utf-8','replace') + +def stream(cmd, to=7200): + enc = base64.b64encode(cmd.encode('utf-16-le')).decode() + stdin, stdout, stderr = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to) + def reader(s): + try: + for line in iter(lambda: s.readline(), ''): + if not line: break + print(line.rstrip(), flush=True) + except Exception: pass + t = threading.Thread(target=reader, args=(stdout,), daemon=True); t.start() + t2 = threading.Thread(target=reader, args=(stderr,), daemon=True); t2.start() + t0 = time.time() + while time.time() - t0 < to: + if stdout.channel.exit_status_ready(): break + time.sleep(1) + t.join(timeout=5); t2.join(timeout=5) + return stdout.channel.recv_exit_status() if stdout.channel.exit_status_ready() else -1 + +print('[1] sftp dfwds-process.js to AD2') +sftp = c.open_sftp() +sftp.put(os.path.join(LOCAL, 'dfwds-process.js'), f'{REMOTE_DIR}/dfwds-process.js') +sftp.close() + +print(f'\n[2] dry-run DFWDS on Test_Datasheets (limit={LIMIT or "all"})') +flags = '--dry-run' +if LIMIT: flags += f' --limit {LIMIT}' +rc = stream(f'cd "{REMOTE_DIR}"; & node dfwds-process.js {flags} 2>&1', to=300) +print(f'[dry-run rc={rc}]') + +if DRY: + print('\n--dry-run flag set on outer script -- stopping here') + c.close(); sys.exit(0) + +print(f'\n[3] LIVE DFWDS run') +flags = '' +if LIMIT: flags = f'--limit {LIMIT}' +rc = stream(f'cd "{REMOTE_DIR}"; & node dfwds-process.js {flags} 2>&1', to=600) +print(f'[live rc={rc}]') + +print('\n[4] regenerate for_web inventory on AD2') +ps_inv = ( + r'$out = "C:\Users\sysadmin\Documents\dataforth-uploader\for_web_inventory.txt"; ' + r'Get-ChildItem "C:\Shares\webshare\For_Web" -File -Filter *.TXT | ' + r'ForEach-Object { "$($_.FullName)|$([System.IO.Path]::GetFileNameWithoutExtension($_.Name))|$($_.Length)|$($_.LastWriteTime.ToString("o"))" } | ' + r'Set-Content -Path $out -Encoding ASCII; ' + r'(Get-Content $out).Count' +) +out = run(ps_inv, to=120) +print(f' for_web entries: {out.strip()}') + +# Pull inventory back to workstation +sftp = c.open_sftp() +sftp.get(f'{REMOTE_DIR}/for_web_inventory.txt', os.path.join(TEMP_DIR, 'for_web_inventory.txt')) +sftp.close() +print(f' pulled to {TEMP_DIR}\\for_web_inventory.txt') + +print('\n[5] fetch fresh server inventory + compute delta locally') +rc = subprocess.run([sys.executable, '-u', os.path.join(LOCAL, 'fetch-server-inventory.py')], + timeout=600).returncode +print(f' fetch-server-inventory rc={rc}') +rc = subprocess.run([sys.executable, '-u', os.path.join(LOCAL, 'compute-delta.py')], + timeout=120).returncode +print(f' compute-delta rc={rc}') + +# Push fresh delta to AD2 +sftp = c.open_sftp() +sftp.put(os.path.join(TEMP_DIR, 'delta_to_upload.txt'), f'{REMOTE_DIR}/delta_to_upload.txt') +sftp.close() + +print('\n[6] run upload-delta.js with fresh delta') +ps_upload = ( + f'$env:CF_TOKEN_URL = "{api["endpoints"]["token-url"]}"; ' + f'$env:CF_API_BASE = "{api["endpoints"]["api-base"]}"; ' + f'$env:CF_CLIENT_ID = "{api["credentials"]["client-id"]}"; ' + f'$env:CF_CLIENT_SECRET = "{api["credentials"]["client-secret"]}"; ' + f'$env:CF_SCOPE = "{api["credentials"]["scope"]}"; ' + f'cd "{REMOTE_DIR}"; ' + f'& node upload-delta.js --batch 100 2>&1' +) +rc = stream(ps_upload, to=3600) +print(f'\n[upload rc={rc}]') + +c.close() +print('\n[OK] full drain complete') diff --git a/projects/dataforth-dos/datasheet-pipeline/run_uploader_on_ad2.py b/projects/dataforth-dos/datasheet-pipeline/run_uploader_on_ad2.py new file mode 100644 index 0000000..5de5fac --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/run_uploader_on_ad2.py @@ -0,0 +1,83 @@ +"""SFTP upload-delta.js + delta_to_upload.txt to AD2, then run via SSH with creds in env vars.""" +import paramiko, subprocess, sys, time, yaml, os + +LIMIT = 0 # 0 = all +BATCH = 100 +DRY = False +START = 0 +# Allow CLI overrides +for i, a in enumerate(sys.argv[1:]): + if a == '--limit': LIMIT = int(sys.argv[i+2]) + if a == '--batch': BATCH = int(sys.argv[i+2]) + if a == '--start': START = int(sys.argv[i+2]) + if a == '--dry-run': DRY = True + +ad2_pwd = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout)['credentials']['password'].replace('\\','') +api = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/api-oauth.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout) + +REMOTE_DIR = 'C:/Users/sysadmin/Documents/dataforth-uploader' +LOCAL_DELTA = r'C:\Users\guru\AppData\Local\Temp\delta_to_upload.txt' +LOCAL_JS = r'D:\claudetools\projects\dataforth-dos\datasheet-pipeline\upload-delta.js' + +c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=ad2_pwd, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) + +def run(cmd, to=120): + _, o, e = c.exec_command(cmd, timeout=to) + return o.read().decode('utf-8','replace'), e.read().decode('utf-8','replace'), o.channel.recv_exit_status() + +print('[1] mkdir + sftp upload') +run(f'powershell -Command "New-Item -ItemType Directory -Force -Path \\"{REMOTE_DIR}\\" | Out-Null"') +sftp = c.open_sftp() +sftp.put(LOCAL_JS, f'{REMOTE_DIR}/upload-delta.js') +sftp.put(LOCAL_DELTA, f'{REMOTE_DIR}/delta_to_upload.txt') +sftp.close() +out, _, _ = run(f'powershell -Command "Get-ChildItem \\"{REMOTE_DIR}\\" | Select Name,Length | Format-Table -AutoSize | Out-String"') +print(out.rstrip()) + +print('\n[2] run uploader on AD2 (env-var creds)') +flags = [] +if LIMIT: flags += ['--limit', str(LIMIT)] +if BATCH: flags += ['--batch', str(BATCH)] +if START: flags += ['--start', str(START)] +if DRY: flags += ['--dry-run'] +flag_str = ' '.join(flags) + +# Build powershell command that sets env vars then runs node +ps_cmd = ( + f'$env:CF_TOKEN_URL = "{api["endpoints"]["token-url"]}"; ' + f'$env:CF_API_BASE = "{api["endpoints"]["api-base"]}"; ' + f'$env:CF_CLIENT_ID = "{api["credentials"]["client-id"]}"; ' + f'$env:CF_CLIENT_SECRET = "{api["credentials"]["client-secret"]}"; ' + f'$env:CF_SCOPE = "{api["credentials"]["scope"]}"; ' + f'cd "{REMOTE_DIR}"; ' + f'& node upload-delta.js {flag_str} 2>&1' +) +import base64 +enc = base64.b64encode(ps_cmd.encode('utf-16-le')).decode() + +stdin, stdout, stderr = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=7200, get_pty=False) +import threading +def reader(stream, label): + try: + for line in iter(lambda: stream.readline(), ''): + if not line: break + print(line.rstrip(), flush=True) + except Exception as e: + print(f'[{label} reader err] {e}') +t = threading.Thread(target=reader, args=(stdout,'out'), daemon=True); t.start() +err_t = threading.Thread(target=reader, args=(stderr,'err'), daemon=True); err_t.start() + +t0 = time.time() +while time.time() - t0 < 7200: + if stdout.channel.exit_status_ready(): break + time.sleep(2) + +t.join(timeout=5) +err_t.join(timeout=5) +rc = stdout.channel.recv_exit_status() if stdout.channel.exit_status_ready() else -1 +print(f'\n[exit {rc}]') +c.close() diff --git a/projects/dataforth-dos/datasheet-pipeline/test-scenarios.py b/projects/dataforth-dos/datasheet-pipeline/test-scenarios.py new file mode 100644 index 0000000..ca9fd1e --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/test-scenarios.py @@ -0,0 +1,143 @@ +"""Run idempotency, update, and bulk tests against the Dataforth API.""" +import json +import urllib.request +import urllib.parse +import hashlib + +import os, sys +TOKEN_URL = os.environ.get("CF_TOKEN_URL", "https://login.dataforth.com/connect/token") +API_BASE = os.environ.get("CF_API_BASE", "https://www.dataforth.com") + "/api/v1" +CLIENT_ID = os.environ.get("CF_CLIENT_ID", "") +CLIENT_SECRET = os.environ.get("CF_CLIENT_SECRET", "") +SCOPE = os.environ.get("CF_SCOPE", "dataforth.web") +if not CLIENT_ID or not CLIENT_SECRET: + sys.exit("set CF_CLIENT_ID + CF_CLIENT_SECRET (vault: clients/dataforth/api-oauth.sops.yaml)") +SAMPLE_DIR = r"D:\claudetools\projects\dataforth-dos\datasheet-pipeline\scmvas-hvas-research\samples\backfill-verify" + + +def get_token(): + data = urllib.parse.urlencode({ + "grant_type": "client_credentials", + "client_id": CLIENT_ID, + "client_secret": CLIENT_SECRET, + "scope": SCOPE, + }).encode() + with urllib.request.urlopen(urllib.request.Request(TOKEN_URL, data=data)) as r: + return json.loads(r.read())["access_token"] + + +def api(method, path, token, body=None): + headers = {"Authorization": f"Bearer {token}"} + data = None + if body is not None: + data = json.dumps(body).encode() + headers["Content-Type"] = "application/json" + req = urllib.request.Request(API_BASE + path, data=data, headers=headers, method=method) + try: + with urllib.request.urlopen(req) as r: + return r.status, r.read().decode() + except urllib.error.HTTPError as e: + return e.code, e.read().decode() + + +def read_sample(sn): + with open(f"{SAMPLE_DIR}\\{sn}-source.txt", "rb") as f: + return f.read().decode("utf-8", errors="replace") + + +def sha16(s): + return hashlib.sha256(s.encode()).hexdigest()[:16] + + +token = get_token() + +# ---------- TEST A: Idempotency ---------- +print("=" * 60) +print("TEST A: Idempotency (re-POST 179377-5 with same content)") +print("=" * 60) +content = read_sample("179377-5") +print(f"Content hash[16]: {sha16(content)}") + +# Baseline stats +status, body = api("GET", "/TestReportDataFiles/stats", token) +stats_before = json.loads(body) +print(f"Stats before: TotalCount={stats_before['TotalCount']}") + +status, body = api("POST", "/TestReportDataFiles", token, + {"SerialNumber": "179377-5", "Content": content}) +print(f"POST same content -> HTTP {status} body: {body}") + +status, body = api("GET", "/TestReportDataFiles/stats", token) +stats_after = json.loads(body) +print(f"Stats after: TotalCount={stats_after['TotalCount']} (delta {stats_after['TotalCount']-stats_before['TotalCount']})") + +status, body = api("GET", "/TestReportDataFiles/179377-5", token) +obj = json.loads(body) +print(f"CreatedAtUtc: {obj.get('CreatedAtUtc')}") +print(f"UpdatedAtUtc: {obj.get('UpdatedAtUtc')}") +print() + +# ---------- TEST B: Update ---------- +print("=" * 60) +print("TEST B: Update (re-POST 179377-5 with MODIFIED content)") +print("=" * 60) +modified = content + "\n[TEST B MODIFICATION MARKER - WILL BE REVERTED]\n" +print(f"Modified hash[16]: {sha16(modified)} (bytes {len(modified.encode())})") + +status, body = api("POST", "/TestReportDataFiles", token, + {"SerialNumber": "179377-5", "Content": modified}) +print(f"POST modified content -> HTTP {status} body: {body}") + +status, body = api("GET", "/TestReportDataFiles/179377-5", token) +obj = json.loads(body) +fetched = obj.get("Content", "") +print(f"Server bytes after update: {len(fetched.encode())} hash[16]: {sha16(fetched)}") +print(f"CreatedAtUtc: {obj.get('CreatedAtUtc')}") +print(f"UpdatedAtUtc: {obj.get('UpdatedAtUtc')} <-- should be non-null now") +print(f"Last line of fetched content: {fetched.rstrip().splitlines()[-1]!r}") +print() + +# ---------- TEST B cleanup: restore ---------- +print("=" * 60) +print("Restoring 179377-5 to original content") +print("=" * 60) +status, body = api("POST", "/TestReportDataFiles", token, + {"SerialNumber": "179377-5", "Content": content}) +print(f"POST original content -> HTTP {status} body: {body}") +status, body = api("GET", "/TestReportDataFiles/179377-5", token) +obj = json.loads(body) +restored_hash = sha16(obj.get("Content", "")) +print(f"Restored hash[16]: {restored_hash} (expect {sha16(content)})") +print(f"Match: {restored_hash == sha16(content)}") +print(f"UpdatedAtUtc: {obj.get('UpdatedAtUtc')}") +print() + +# ---------- TEST C: Bulk ---------- +print("=" * 60) +print("TEST C: Bulk upload (179377-7, -8, -9)") +print("=" * 60) +items = [] +for sn in ["179377-7", "179377-8", "179377-9"]: + c = read_sample(sn) + items.append({"SerialNumber": sn, "Content": c}) + print(f" Staged {sn}: {len(c.encode())} bytes, hash[16]={sha16(c)}") + +status, body = api("POST", "/TestReportDataFiles/bulk", token, {"Items": items}) +print(f"\nPOST /bulk -> HTTP {status}") +print(f"Response: {body}") +print() + +for sn in ["179377-7", "179377-8", "179377-9"]: + status, body = api("GET", f"/TestReportDataFiles/{sn}", token) + if status == 200: + o = json.loads(body) + local = read_sample(sn) + match = "MATCH" if sha16(local) == sha16(o.get("Content", "")) else "DIFF" + print(f" {sn}: GET {status} content {match}, Created={o.get('CreatedAtUtc')}") + else: + print(f" {sn}: GET {status} body={body}") + +# Final stats +status, body = api("GET", "/TestReportDataFiles/stats", token) +stats_final = json.loads(body) +print(f"\nFinal TotalCount: {stats_final['TotalCount']} (started at {stats_before['TotalCount']})") diff --git a/projects/dataforth-dos/datasheet-pipeline/test-upload-two.py b/projects/dataforth-dos/datasheet-pipeline/test-upload-two.py new file mode 100644 index 0000000..131be05 --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/test-upload-two.py @@ -0,0 +1,94 @@ +"""Upload two real datasheets, fetch them back, diff byte-for-byte.""" +import json +import sys +import urllib.request +import urllib.parse +import hashlib + +import os, sys +TOKEN_URL = os.environ.get("CF_TOKEN_URL", "https://login.dataforth.com/connect/token") +API_BASE = os.environ.get("CF_API_BASE", "https://www.dataforth.com") + "/api/v1" +CLIENT_ID = os.environ.get("CF_CLIENT_ID", "") +CLIENT_SECRET = os.environ.get("CF_CLIENT_SECRET", "") +SCOPE = os.environ.get("CF_SCOPE", "dataforth.web") +if not CLIENT_ID or not CLIENT_SECRET: + sys.exit("set CF_CLIENT_ID + CF_CLIENT_SECRET (vault: clients/dataforth/api-oauth.sops.yaml)") + +SAMPLES = [ + ("179377-5", r"D:\claudetools\projects\dataforth-dos\datasheet-pipeline\scmvas-hvas-research\samples\backfill-verify\179377-5-source.txt"), + ("179377-6", r"D:\claudetools\projects\dataforth-dos\datasheet-pipeline\scmvas-hvas-research\samples\backfill-verify\179377-6-source.txt"), +] + + +def get_token(): + data = urllib.parse.urlencode({ + "grant_type": "client_credentials", + "client_id": CLIENT_ID, + "client_secret": CLIENT_SECRET, + "scope": SCOPE, + }).encode() + req = urllib.request.Request(TOKEN_URL, data=data) + with urllib.request.urlopen(req) as r: + return json.loads(r.read())["access_token"] + + +def api(method, path, token, body=None): + url = API_BASE + path + headers = {"Authorization": f"Bearer {token}"} + if body is not None: + body = json.dumps(body).encode() + headers["Content-Type"] = "application/json" + req = urllib.request.Request(url, data=body, headers=headers, method=method) + try: + with urllib.request.urlopen(req) as r: + return r.status, r.read().decode() + except urllib.error.HTTPError as e: + return e.code, e.read().decode() + + +def main(): + token = get_token() + print(f"[OK] Got access token (len={len(token)})\n") + + for sn, path in SAMPLES: + with open(path, "rb") as f: + content_bytes = f.read() + content = content_bytes.decode("utf-8", errors="replace") + local_hash = hashlib.sha256(content.encode()).hexdigest()[:16] + print(f"=== {sn} ===") + print(f" Local file: {path}") + print(f" Local bytes: {len(content_bytes)} sha256[16]: {local_hash}") + + status, body = api("POST", "/TestReportDataFiles", token, + {"SerialNumber": sn, "Content": content}) + print(f" POST -> HTTP {status}") + print(f" Server response: {body}") + + status, body = api("GET", f"/TestReportDataFiles/{sn}", token) + print(f" GET -> HTTP {status}") + if status != 200: + print(f" !! Fetch failed: {body}") + continue + obj = json.loads(body) + fetched = obj.get("Content", "") + fetched_hash = hashlib.sha256(fetched.encode()).hexdigest()[:16] + print(f" Server bytes: {len(fetched.encode('utf-8'))} sha256[16]: {fetched_hash}") + match = "MATCH" if content == fetched else "DIFF" + print(f" Content match: {match}") + print(f" CreatedAtUtc: {obj.get('CreatedAtUtc')}") + print(f" UpdatedAtUtc: {obj.get('UpdatedAtUtc')}") + + if content != fetched: + # Show first diff + for i, (a, b) in enumerate(zip(content, fetched)): + if a != b: + print(f" First diff at char {i}: local={a!r} server={b!r}") + print(f" context: ...{content[max(0,i-20):i+20]!r}") + break + else: + print(f" Length diff: local={len(content)} server={len(fetched)}") + print() + + +if __name__ == "__main__": + main() diff --git a/projects/dataforth-dos/datasheet-pipeline/upload-delta.js b/projects/dataforth-dos/datasheet-pipeline/upload-delta.js new file mode 100644 index 0000000..9faaee7 --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/upload-delta.js @@ -0,0 +1,204 @@ +/** + * Bulk-upload delta to Dataforth API. + * + * Reads delta_to_upload.txt (pipe-delimited: SerialNumber|Path|Size|MTime), + * batches into POST /api/v1/TestReportDataFiles/bulk, refreshes token before + * expiry, logs result line-by-line. + * + * Required env vars: + * CF_TOKEN_URL, CF_API_BASE, CF_CLIENT_ID, CF_CLIENT_SECRET, CF_SCOPE + * + * Usage: node upload-delta.js [--delta path] [--batch 100] [--limit N] + * [--start N] [--dry-run] + */ +const fs = require('fs'); +const path = require('path'); +const https = require('https'); +const url = require('url'); + +const args = process.argv.slice(2); +function arg(name, dflt) { + const i = args.indexOf(name); + if (i < 0) return dflt; + return args[i+1]; +} +const flag = (name) => args.includes(name); + +const DELTA = arg('--delta', 'C:\\Users\\sysadmin\\Documents\\dataforth-uploader\\delta_to_upload.txt'); +const BATCH = parseInt(arg('--batch', '100'), 10); +const LIMIT = parseInt(arg('--limit', '0'), 10); +const START = parseInt(arg('--start', '0'), 10); +const DRY = flag('--dry-run'); + +const CRED = { + tokenUrl: process.env.CF_TOKEN_URL, + apiBase: process.env.CF_API_BASE, + clientId: process.env.CF_CLIENT_ID, + clientSecret: process.env.CF_CLIENT_SECRET, + scope: process.env.CF_SCOPE, +}; +for (const k of Object.keys(CRED)) { + if (!CRED[k] && !DRY) { console.error(`[FAIL] missing env var for ${k}`); process.exit(1); } +} + +const LOG_DIR = path.join(path.dirname(DELTA), 'upload-logs'); +fs.mkdirSync(LOG_DIR, {recursive: true}); +const LOG_PATH = path.join(LOG_DIR, `upload-${new Date().toISOString().replace(/[:.]/g,'-').slice(0,19)}.log`); +const log = fs.createWriteStream(LOG_PATH); + +let tokenCache = {value: null, expiresAt: 0}; + +function postForm(uri, formObj) { + return new Promise((resolve, reject) => { + const u = new url.URL(uri); + const body = Object.entries(formObj).map(([k,v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&'); + const req = https.request({ + hostname: u.hostname, port: u.port||443, path: u.pathname + u.search, + method:'POST', + headers:{'Content-Type':'application/x-www-form-urlencoded','Content-Length':Buffer.byteLength(body)}, + timeout: 30000, + }, res => { + let data=''; res.on('data', c => data+=c); + res.on('end', () => { + try { resolve({status:res.statusCode, body:JSON.parse(data)}); } + catch (e) { resolve({status:res.statusCode, body:{_raw:data}}); } + }); + }); + req.on('error', reject); req.on('timeout', () => req.destroy(new Error('timeout'))); + req.write(body); req.end(); + }); +} + +function postJson(uri, jsonObj, token) { + return new Promise((resolve, reject) => { + const u = new url.URL(uri); + const body = JSON.stringify(jsonObj); + const req = https.request({ + hostname: u.hostname, port: u.port||443, path: u.pathname + u.search, + method:'POST', + headers:{ + 'Authorization':`Bearer ${token}`, + 'Content-Type':'application/json', + 'Content-Length':Buffer.byteLength(body), + }, + timeout: 180000, + }, res => { + let data=''; res.on('data', c => data+=c); + res.on('end', () => { + try { resolve({status:res.statusCode, body:JSON.parse(data)}); } + catch (e) { resolve({status:res.statusCode, body:{_raw:data}}); } + }); + }); + req.on('error', reject); req.on('timeout', () => req.destroy(new Error('timeout'))); + req.write(body); req.end(); + }); +} + +async function getToken(force=false) { + if (!force && tokenCache.value && Date.now() < tokenCache.expiresAt - 60000) { + return tokenCache.value; + } + const r = await postForm(CRED.tokenUrl, { + grant_type: 'client_credentials', + client_id: CRED.clientId, + client_secret: CRED.clientSecret, + scope: CRED.scope, + }); + if (r.status !== 200 || !r.body.access_token) { + throw new Error(`token fetch failed: ${r.status} ${JSON.stringify(r.body)}`); + } + tokenCache.value = r.body.access_token; + tokenCache.expiresAt = Date.now() + (r.body.expires_in || 3600) * 1000; + return tokenCache.value; +} + +async function bulkUpload(items) { + for (let attempt = 0; attempt < 2; attempt++) { + const token = await getToken(attempt > 0); + try { + const r = await postJson(`${CRED.apiBase}/api/v1/TestReportDataFiles/bulk`, {Items: items}, token); + if (r.status === 401 && attempt === 0) continue; + return r; + } catch (e) { + if (attempt === 0) { await new Promise(r => setTimeout(r, 5000)); continue; } + return {status: 0, body: {_error: e.message}}; + } + } +} + +function loadDelta() { + const items = []; + const lines = fs.readFileSync(DELTA, 'utf-8').split(/\r?\n/); + for (let i = 0; i < lines.length; i++) { + if (i < START) continue; + if (LIMIT && items.length >= LIMIT) break; + const parts = lines[i].split('|'); + if (parts.length < 4) continue; + items.push({sn: parts[0], path: parts[1], size: parseInt(parts[2],10) || 0}); + } + return items; +} + +(async () => { + console.log(`[INFO] delta file: ${DELTA}`); + console.log(`[INFO] log file: ${LOG_PATH}`); + const items = loadDelta(); + console.log(`[INFO] ${items.length} items queued (start=${START} limit=${LIMIT||'all'} batch=${BATCH})`); + console.log(`[INFO] dry-run: ${DRY}`); + log.write(`# upload run ${new Date().toISOString()}\n`); + log.write(`# delta=${items.length} batch=${BATCH} dry=${DRY}\n`); + + if (!DRY) { + const t = await getToken(); + console.log(`[OK] token len=${t.length}`); + } + + const totals = {received:0, created:0, updated:0, unchanged:0, errors:0}; + const t0 = Date.now(); + const nBatches = Math.ceil(items.length / BATCH); + + for (let i = 0; i < items.length; i += BATCH) { + const chunk = items.slice(i, i + BATCH); + const bulk = []; + for (const it of chunk) { + try { + const buf = fs.readFileSync(it.path); + bulk.push({SerialNumber: it.sn, Content: buf.toString('utf-8')}); + } catch (e) { + log.write(`READ_FAIL ${it.sn} ${it.path} ${e.message}\n`); + totals.errors++; + } + } + if (DRY) { + console.log(` [DRY] batch ${(i/BATCH)+1}/${nBatches}: ${bulk.length} items`); + continue; + } + const r = await bulkUpload(bulk); + if (r.status !== 200) { + console.log(` [FAIL] batch ${(i/BATCH)+1} HTTP ${r.status}: ${JSON.stringify(r.body).slice(0,300)}`); + log.write(`BATCH_FAIL idx=${i} status=${r.status} body=${JSON.stringify(r.body).slice(0,500)}\n`); + totals.errors += bulk.length; + continue; + } + totals.received += r.body.TotalReceived || 0; + totals.created += r.body.Created || 0; + totals.updated += r.body.Updated || 0; + totals.unchanged += r.body.Unchanged || 0; + for (const e of (r.body.Errors || [])) { + log.write(`BATCH_ITEM_ERR ${e}\n`); + totals.errors++; + } + const done = i + chunk.length; + const rate = done / Math.max(1, (Date.now()-t0)/1000); + const etaS = Math.round((items.length - done) / Math.max(1, rate)); + console.log(` batch ${(i/BATCH)+1}/${nBatches}: recv=${r.body.TotalReceived} cre=${r.body.Created} upd=${r.body.Updated} unch=${r.body.Unchanged} err=${(r.body.Errors||[]).length} | rate=${rate.toFixed(0)}/s eta=${etaS}s`); + log.write(`BATCH idx=${i} rcv=${r.body.TotalReceived} cre=${r.body.Created} upd=${r.body.Updated} unch=${r.body.Unchanged} err=${(r.body.Errors||[]).length}\n`); + } + + const elapsed = (Date.now() - t0) / 1000; + console.log(`\n[DONE] elapsed ${elapsed.toFixed(1)}s`); + for (const [k,v] of Object.entries(totals)) console.log(` ${k}: ${v}`); + log.write(`\n# totals ${JSON.stringify(totals)}\n# elapsed ${elapsed.toFixed(1)}s\n`); + log.end(); + console.log(`[INFO] log: ${LOG_PATH}`); +})().catch(e => { console.error('[FATAL]', e); process.exit(1); }); diff --git a/projects/dataforth-dos/datasheet-pipeline/upload-delta.py b/projects/dataforth-dos/datasheet-pipeline/upload-delta.py new file mode 100644 index 0000000..c2f24f5 --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/upload-delta.py @@ -0,0 +1,162 @@ +"""Bulk-upload the delta to Hoffman's API. + +Reads delta_to_upload.txt (produced by compute-delta.py), POSTs to +/api/v1/TestReportDataFiles/bulk in batches, retries on transient errors, +refreshes token before expiry, logs results. + +Usage: + python upload-delta.py [--batch 100] [--dry-run] [--limit N] [--start N] +""" +import argparse, json, os, subprocess, sys, time, urllib.request, urllib.error, urllib.parse +import yaml + +DELTA = r'C:\Users\guru\AppData\Local\Temp\delta_to_upload.txt' +LOG_DIR = r'D:\claudetools\projects\dataforth-dos\datasheet-pipeline\upload-logs' +os.makedirs(LOG_DIR, exist_ok=True) +LOG_PATH = os.path.join(LOG_DIR, time.strftime('upload-%Y%m%d-%H%M%S.log')) + +VAULT = 'D:/vault/clients/dataforth/api-oauth.sops.yaml' + +def load_creds(): + r = subprocess.run(['sops','-d',VAULT], capture_output=True, text=True, timeout=30, check=True) + y = yaml.safe_load(r.stdout) + return { + 'token_url': y['endpoints']['token-url'], + 'api_base': y['endpoints']['api-base'], + 'client_id': y['credentials']['client-id'], + 'client_secret': y['credentials']['client-secret'], + 'scope': y['credentials']['scope'], + } + +CREDS = load_creds() +_token = {'value': None, 'expires_at': 0} + +def get_token(force=False): + if not force and _token['value'] and time.time() < _token['expires_at'] - 60: + return _token['value'] + body = urllib.parse.urlencode({ + 'grant_type':'client_credentials', + 'client_id':CREDS['client_id'], + 'client_secret':CREDS['client_secret'], + 'scope':CREDS['scope'], + }).encode() + req = urllib.request.Request(CREDS['token_url'], data=body, method='POST', + headers={'Content-Type':'application/x-www-form-urlencoded'}) + with urllib.request.urlopen(req, timeout=30) as r: + t = json.loads(r.read()) + _token['value'] = t['access_token'] + _token['expires_at'] = time.time() + t.get('expires_in', 3600) + return _token['value'] + +def api_post(path, body): + """POST with one retry on 401/transient.""" + url = f"{CREDS['api_base']}{path}" + data = json.dumps(body).encode() + for attempt in range(2): + token = get_token(force=(attempt > 0)) + req = urllib.request.Request(url, data=data, method='POST', + headers={'Authorization':f'Bearer {token}','Content-Type':'application/json'}) + try: + with urllib.request.urlopen(req, timeout=120) as r: + return r.status, json.loads(r.read()) + except urllib.error.HTTPError as e: + if e.code == 401 and attempt == 0: + continue + try: return e.code, json.loads(e.read()) + except Exception: return e.code, {'_raw': e.read().decode(errors='replace')[:500]} + except (urllib.error.URLError, TimeoutError) as e: + if attempt == 0: + time.sleep(5); continue + return 0, {'_error': str(e)} + +def load_delta(start=0, limit=0): + items = [] + with open(DELTA, encoding='utf-8') as f: + for i, line in enumerate(f): + if i < start: continue + if limit and len(items) >= limit: break + parts = line.rstrip('\n').split('|') + if len(parts) < 4: continue + sn, path, size, mtime = parts[0], parts[1], parts[2], parts[3] + items.append({'sn': sn, 'path': path, 'size': int(size)}) + return items + +def read_content(path): + with open(path, 'rb') as f: + return f.read().decode('utf-8', errors='replace') + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('--batch', type=int, default=100, help='items per /bulk POST') + ap.add_argument('--dry-run', action='store_true') + ap.add_argument('--limit', type=int, default=0, help='cap total processed (0 = all)') + ap.add_argument('--start', type=int, default=0, help='skip first N rows in delta file') + args = ap.parse_args() + + print(f'[INFO] delta file: {DELTA}') + print(f'[INFO] log file: {LOG_PATH}') + items = load_delta(start=args.start, limit=args.limit) + print(f'[INFO] {len(items)} items queued (start={args.start} limit={args.limit or "all"}, batch={args.batch})') + print(f'[INFO] dry-run: {args.dry_run}') + + if not args.dry_run: + token = get_token() + print(f'[OK] token len={len(token)}') + + log = open(LOG_PATH, 'w', encoding='utf-8') + log.write(f'# upload run {time.strftime("%Y-%m-%d %H:%M:%S")}\n') + log.write(f'# delta size: {len(items)}, batch: {args.batch}, dry_run: {args.dry_run}\n') + + totals = {'received':0,'created':0,'updated':0,'unchanged':0,'errors':0} + t0 = time.time() + n = len(items) + for i in range(0, n, args.batch): + chunk = items[i:i+args.batch] + # Read file content for each + bulk = [] + for it in chunk: + try: + bulk.append({'SerialNumber': it['sn'], 'Content': read_content(it['path'])}) + except Exception as e: + log.write(f'READ_FAIL {it["sn"]} {it["path"]} {e}\n') + totals['errors'] += 1 + + if args.dry_run: + print(f' [DRY] batch {i//args.batch + 1}: {len(bulk)} items (first sn={bulk[0]["SerialNumber"] if bulk else "-"})') + continue + + status, resp = api_post('/api/v1/TestReportDataFiles/bulk', {'Items': bulk}) + if status != 200: + print(f' [FAIL] batch {i//args.batch+1} HTTP {status}: {resp}') + log.write(f'BATCH_FAIL idx={i} status={status} resp={resp}\n') + totals['errors'] += len(bulk) + continue + totals['received'] += resp.get('TotalReceived', 0) + totals['created'] += resp.get('Created', 0) + totals['updated'] += resp.get('Updated', 0) + totals['unchanged']+= resp.get('Unchanged', 0) + for err in (resp.get('Errors') or []): + log.write(f'BATCH_ITEM_ERR {err}\n') + totals['errors'] += 1 + + rate = (i + len(chunk)) / max(1, time.time() - t0) + eta_s = int((n - (i + len(chunk))) / max(1, rate)) + print(f' batch {i//args.batch+1:>4}/{(n+args.batch-1)//args.batch}: ' + f'recv={resp.get("TotalReceived",0)} ' + f'cre={resp.get("Created",0)} upd={resp.get("Updated",0)} unch={resp.get("Unchanged",0)} ' + f'err={len(resp.get("Errors") or [])} | rate={rate:.0f}/s eta={eta_s}s') + log.write(f'BATCH idx={i} rcv={resp.get("TotalReceived")} cre={resp.get("Created")} upd={resp.get("Updated")} unch={resp.get("Unchanged")} err={len(resp.get("Errors") or [])}\n') + + elapsed = time.time() - t0 + print(f'\n[DONE] elapsed {elapsed:.1f}s') + print(f' received: {totals["received"]}') + print(f' created: {totals["created"]}') + print(f' updated: {totals["updated"]}') + print(f' unchanged: {totals["unchanged"]}') + print(f' errors: {totals["errors"]}') + log.write(f'\n# totals: {totals}\n# elapsed: {elapsed:.1f}s\n') + log.close() + print(f'[INFO] log: {LOG_PATH}') + +if __name__ == '__main__': + main() diff --git a/projects/dataforth-dos/datasheet-pipeline/upload_all_for_web.py b/projects/dataforth-dos/datasheet-pipeline/upload_all_for_web.py new file mode 100644 index 0000000..c1d2ec9 --- /dev/null +++ b/projects/dataforth-dos/datasheet-pipeline/upload_all_for_web.py @@ -0,0 +1,79 @@ +"""Build delta = entire For_Web folder, upload via upload-delta.js. + +Server is idempotent; already-present items return Unchanged, new ones Created. +Avoids the slow full server-inventory pull when we just want to drain new content. +""" +import base64, paramiko, subprocess, time, threading, yaml + +ad2_pwd = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout)['credentials']['password'].replace('\\','') +api = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/api-oauth.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout) + +REMOTE_DIR = 'C:/Users/sysadmin/Documents/dataforth-uploader' +DELTA_NAME = 'delta_for_web_all.txt' + +c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=ad2_pwd, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) + +def ps_b64(cmd, to=300): + enc = base64.b64encode(cmd.encode('utf-16-le')).decode() + _, o, e = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to) + return o.read().decode('utf-8','replace'), e.read().decode('utf-8','replace') + +print('[1] enumerate For_Web on AD2') +ps = ( + f'$out = "{REMOTE_DIR}/{DELTA_NAME}"; ' + r'Get-ChildItem "C:\Shares\webshare\For_Web" -File -Filter *.TXT | ' + r'ForEach-Object { ' + r' $sn = [System.IO.Path]::GetFileNameWithoutExtension($_.Name); ' + r' "$sn|$($_.FullName)|$($_.Length)|$($_.LastWriteTime.ToString("o"))" ' + r'} | Set-Content -Path $out -Encoding ASCII; ' + r'(Get-Content $out).Count' +) +out, err = ps_b64(ps, to=180) +print(f' delta entries: {out.strip()}') +if err.strip() and 'CLIXML' not in err: print('[stderr]', err[:300]) + +print('\n[2] upload all via upload-delta.js (idempotent)') +ps_upload = ( + f'$env:CF_TOKEN_URL = "{api["endpoints"]["token-url"]}"; ' + f'$env:CF_API_BASE = "{api["endpoints"]["api-base"]}"; ' + f'$env:CF_CLIENT_ID = "{api["credentials"]["client-id"]}"; ' + f'$env:CF_CLIENT_SECRET = "{api["credentials"]["client-secret"]}"; ' + f'$env:CF_SCOPE = "{api["credentials"]["scope"]}"; ' + f'cd "{REMOTE_DIR}"; ' + f'& node upload-delta.js --delta "{REMOTE_DIR}/{DELTA_NAME}" --batch 100 2>&1' +) +enc = base64.b64encode(ps_upload.encode('utf-16-le')).decode() +stdin, stdout, stderr = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=3600) + +def reader(s): + for line in iter(lambda: s.readline(), ''): + if not line: break + print(line.rstrip(), flush=True) +t = threading.Thread(target=reader, args=(stdout,), daemon=True); t.start() +t2 = threading.Thread(target=reader, args=(stderr,), daemon=True); t2.start() +t0 = time.time() +while time.time() - t0 < 3600: + if stdout.channel.exit_status_ready(): break + time.sleep(1) +t.join(timeout=5); t2.join(timeout=5) +rc = stdout.channel.recv_exit_status() if stdout.channel.exit_status_ready() else -1 +print(f'\n[upload rc={rc}]') + +print('\n[3] post-upload server stats') +import json, urllib.request, urllib.parse +body = urllib.parse.urlencode({'grant_type':api['credentials']['grant-type'], + 'client_id':api['credentials']['client-id'], + 'client_secret':api['credentials']['client-secret'], + 'scope':api['credentials']['scope']}).encode() +req = urllib.request.Request(api['endpoints']['token-url'], data=body, method='POST', + headers={'Content-Type':'application/x-www-form-urlencoded'}) +tok = json.loads(urllib.request.urlopen(req,timeout=30).read())['access_token'] +req = urllib.request.Request(f'{api["endpoints"]["api-base"]}/api/v1/TestReportDataFiles/stats', + headers={'Authorization':f'Bearer {tok}'}) +print(json.dumps(json.loads(urllib.request.urlopen(req,timeout=30).read()), indent=2)) + +c.close() diff --git a/projects/dataforth-dos/dfwds-research/api_probe.py b/projects/dataforth-dos/dfwds-research/api_probe.py new file mode 100644 index 0000000..5439776 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/api_probe.py @@ -0,0 +1,47 @@ +"""Probe Dataforth API: get token, fetch Swagger, list relevant endpoints.""" +import json, os, subprocess, urllib.request +import yaml + +creds = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/api-oauth.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout) +TOKEN_URL = creds['endpoints']['token-url'] +SWAGGER_JSON = creds['endpoints']['swagger-json'] +API_BASE = creds['endpoints']['api-base'] +C = creds['credentials'] + +# 1. Get token +print('[1] fetch OAuth token') +body = (f'grant_type={C["grant-type"]}&client_id={C["client-id"]}' + f'&client_secret={C["client-secret"]}&scope={C["scope"]}').encode() +req = urllib.request.Request(TOKEN_URL, data=body, method='POST', + headers={'Content-Type':'application/x-www-form-urlencoded'}) +with urllib.request.urlopen(req, timeout=30) as r: + tok = json.loads(r.read()) +print(f' access_token: {tok["access_token"][:30]}... (expires_in={tok.get("expires_in")}s)') +ACCESS = tok['access_token'] + +# 2. Pull swagger +print('\n[2] fetch swagger') +req = urllib.request.Request(SWAGGER_JSON, + headers={'Authorization': f'Bearer {ACCESS}'}) +with urllib.request.urlopen(req, timeout=30) as r: + sw = json.loads(r.read()) +print(f' title: {sw.get("info",{}).get("title")}, version: {sw.get("info",{}).get("version")}') +print(f' total paths: {len(sw.get("paths",{}))}') + +# 3. Filter paths for upload/datasheet/file/test +print('\n[3] paths matching upload/datasheet/file/test/report:') +hits = [] +for path, methods in sw.get('paths',{}).items(): + pl = path.lower() + if any(k in pl for k in ('upload','datasheet','testreport','file','data')): + for m, op in methods.items(): + if m.startswith('x-'): continue + hits.append((m.upper(), path, op.get('summary','') or op.get('operationId',''))) +for m,p,desc in sorted(hits)[:40]: + print(f' {m:6} {p:60} {desc[:60]}') + +# 4. Save full swagger for offline reading +out = r'D:\claudetools\projects\dataforth-dos\dfwds-research\swagger.json' +with open(out,'w',encoding='utf-8') as f: json.dump(sw, f, indent=2) +print(f'\nfull swagger saved: {out}') diff --git a/projects/dataforth-dos/dfwds-research/check_x_drive.py b/projects/dataforth-dos/dfwds-research/check_x_drive.py new file mode 100644 index 0000000..c64d698 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/check_x_drive.py @@ -0,0 +1,43 @@ +"""Check X: drive folders to see what DFWDS would have to process.""" +import base64, paramiko, subprocess, yaml + +pwd_raw = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True).stdout)['credentials']['password'] +PWD = pwd_raw.replace('\\', '') + +c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=PWD, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) + +def ps(cmd, to=120): + enc = base64.b64encode(cmd.encode('utf-16-le')).decode() + _, o, e = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to) + return o.read().decode('utf-8','replace'), e.read().decode('utf-8','replace') + +paths = [ + r'\\ad2\webshare\Test_Datasheets', + r'\\ad2\webshare\Bad_Datasheets', + r'\\ad2\webshare\For_Web', + r'\\ad2\webshare\Datasheets_Log', +] +for p in paths: + print(f'\n=== {p} ===') + out, err = ps(f''' +if (Test-Path "{p}") {{ + $f = Get-ChildItem -LiteralPath "{p}" -File -ErrorAction SilentlyContinue + "files: $($f.Count)" + if ($f.Count -gt 0) {{ + "bytes: $(($f | Measure-Object Length -Sum).Sum)" + "oldest: $(($f | Sort-Object LastWriteTime | Select-Object -First 1).LastWriteTime)" + "newest: $(($f | Sort-Object LastWriteTime | Select-Object -Last 1).LastWriteTime)" + "first 5 by name:" + $f | Sort-Object Name | Select-Object -First 5 Name,Length,LastWriteTime | Format-Table -AutoSize | Out-String + "newest 5:" + $f | Sort-Object LastWriteTime -Descending | Select-Object -First 5 Name,Length,LastWriteTime | Format-Table -AutoSize | Out-String + }} +}} else {{ "PATH MISSING" }} +''') + print(out.rstrip()) + if err.strip() and 'CLIXML' not in err: print('[stderr]', err[:200]) + +c.close() diff --git a/projects/dataforth-dos/dfwds-research/fetch_dfwds.py b/projects/dataforth-dos/dfwds-research/fetch_dfwds.py new file mode 100644 index 0000000..16665d9 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/fetch_dfwds.py @@ -0,0 +1,72 @@ +"""Pull the entire DFWDS tree from AD1 to local.""" +import base64, os, posixpath, paramiko, subprocess, yaml + +LOCAL = r'D:\claudetools\projects\dataforth-dos\dfwds-research\source' +REMOTE_BASE = r'\\AD1\Engineering\ENGR\ATE\Test Datasheets\DFWDS' +AD2_STAGE = r'C:\Users\sysadmin\Documents\dfwds_stage' + +pwd_raw = yaml.safe_load(subprocess.run( + ['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True, +).stdout)['credentials']['password'] +PWD = pwd_raw.replace('\\', '') + +c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=PWD, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) + +def ps(cmd, to=300): + enc = base64.b64encode(cmd.encode('utf-16-le')).decode() + _, o, e = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to) + return o.read().decode('utf-8','replace'), e.read().decode('utf-8','replace') + +# 1. Stage on AD2 (recursive copy) +print('[1] copying tree to AD2 stage', flush=True) +out, err = ps(f''' +if (Test-Path "{AD2_STAGE}") {{ Remove-Item -Recurse -Force "{AD2_STAGE}" }} +Copy-Item -LiteralPath "{REMOTE_BASE}" -Destination "{AD2_STAGE}" -Recurse -Force -ErrorAction Stop +$f = Get-ChildItem -LiteralPath "{AD2_STAGE}" -Recurse -File +"copied: $($f.Count) files, $(($f | Measure-Object Length -Sum).Sum) bytes" +''') +print(out.rstrip()) +if err.strip() and 'CLIXML' not in err: print('[stderr]', err[:400]) + +# 2. SFTP recursive download +print('\n[2] SFTP-pulling to local', flush=True) +sftp = c.open_sftp() + +def walk_remote(base): + """Yield (relpath, is_dir, size) for every entry under base.""" + stack = [''] + while stack: + rel = stack.pop() + for entry in sftp.listdir_attr(f'{base}/{rel}' if rel else base): + entry_rel = f'{rel}/{entry.filename}' if rel else entry.filename + from stat import S_ISDIR + is_dir = S_ISDIR(entry.st_mode) + yield entry_rel, is_dir, entry.st_size + if is_dir: + stack.append(entry_rel) + +stage_posix = AD2_STAGE.replace('\\','/') +n_files = 0 +n_bytes = 0 +for rel, is_dir, sz in walk_remote(stage_posix): + local_path = os.path.join(LOCAL, rel.replace('/', os.sep)) + if is_dir: + os.makedirs(local_path, exist_ok=True) + else: + os.makedirs(os.path.dirname(local_path), exist_ok=True) + sftp.get(f'{stage_posix}/{rel}', local_path) + n_files += 1 + n_bytes += sz + +print(f' pulled {n_files} files, {n_bytes:,} bytes', flush=True) +sftp.close() + +# 3. Cleanup AD2 stage +print('\n[3] cleanup AD2 stage', flush=True) +ps(f'Remove-Item -Recurse -Force "{AD2_STAGE}"') +print('[OK]', flush=True) + +c.close() diff --git a/projects/dataforth-dos/dfwds-research/probe_dfwds.py b/projects/dataforth-dos/dfwds-research/probe_dfwds.py new file mode 100644 index 0000000..1b45276 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/probe_dfwds.py @@ -0,0 +1,34 @@ +"""Probe DFWDS folder on AD1 via AD2.""" +import base64, paramiko, subprocess, yaml + +pwd_raw = yaml.safe_load(subprocess.run( + ['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'], + capture_output=True, text=True, timeout=30, check=True, +).stdout)['credentials']['password'] +PWD = pwd_raw.replace('\\', '') + +c = paramiko.SSHClient() +c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +c.connect('192.168.0.6', username='sysadmin', password=PWD, + timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False) + +def ps(cmd, to=180): + enc = base64.b64encode(cmd.encode('utf-16-le')).decode() + _, o, e = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to) + return o.read().decode('utf-8','replace'), e.read().decode('utf-8','replace') + +BASE = r'\\AD1\Engineering\ENGR\ATE\Test Datasheets\DFWDS' + +print(f'=== top-level: {BASE} ===') +out, err = ps(f'Get-ChildItem -LiteralPath "{BASE}" -Force | Select Name,Mode,Length,LastWriteTime | Format-Table -AutoSize | Out-String') +print(out) + +print('\n=== recursive count + total bytes ===') +out, err = ps(f'$f = Get-ChildItem -LiteralPath "{BASE}" -Recurse -File -ErrorAction SilentlyContinue; "files: $($f.Count)"; "bytes: $(($f | Measure-Object Length -Sum).Sum)"') +print(out) + +print('\n=== full recursive listing (first 100) ===') +out, err = ps(f'Get-ChildItem -LiteralPath "{BASE}" -Recurse -File -ErrorAction SilentlyContinue | Select-Object -First 100 FullName,Length,LastWriteTime | Format-Table -AutoSize | Out-String') +print(out[:6000]) + +c.close() diff --git a/projects/dataforth-dos/dfwds-research/source/Program/DFWDS_NAMES.txt b/projects/dataforth-dos/dfwds-research/source/Program/DFWDS_NAMES.txt new file mode 100644 index 0000000..cc4dab1 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Program/DFWDS_NAMES.txt @@ -0,0 +1,80 @@ +DATASHEET FOLDER NAME,X:\Test_Datasheets +INVALID FILE MOVE FOLDER,X:\Bad_Datasheets +LOG FILE NAME,DFWDS +LOG FILE FOLDER,X:\Datasheets_Log +WEB FOLDER,X:\For_Web +OPERATION,WEBMOVE + +Last updated: 2015-06-08 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +----------- +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +------------ +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +----------- +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +------------ +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +----------- +OPERATION: This parameter controls the operation of the program, and +can only be one of the values described below: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/Program/Dataforth Website Datasheets Rename and Move Program.lnk b/projects/dataforth-dos/dfwds-research/source/Program/Dataforth Website Datasheets Rename and Move Program.lnk new file mode 100644 index 0000000..ee6f36f Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Program/Dataforth Website Datasheets Rename and Move Program.lnk differ diff --git a/projects/dataforth-dos/dfwds-research/source/Program/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/Program/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Program/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/Program/Readme.txt b/projects/dataforth-dos/dfwds-research/source/Program/Readme.txt new file mode 100644 index 0000000..f082495 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Program/Readme.txt @@ -0,0 +1,4 @@ +The "Dataforth.ico" and "DFWDS_NAMES.txt" files should be in the same directory as the "DFWDS.exe" executable file. The "DFWDS_NAMES.txt" file contents should point to the appropriate folders on the "X:" drive ("\\ad2\WebShare"). + +Use the "Dataforth Website Datasheets Rename and Move Program" shortcut to run the program from the "K:\DFWDS\Program" folder. + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.bas new file mode 100644 index 0000000..7decc19 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.bas @@ -0,0 +1,1181 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2015_06_08" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/29 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = This file, the main code module. +' VB FORMS: frmSplash.frm = Program "splash" form displayed while the program is running. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/29 PWR Initial version. +' 2014/06/08 PWR Updated to move already-valid and renamed datasheet files to the "web folder" location and +' to properly parse and check "operations" specified in the "names" file. +' NOTE: The operations specified are currently ignored, apart from checking for valid +' operations strings in the "names" file. The program currently always performs +' the equivalent of the "WEBMOVE" operation: +' 1) Move invalid ("bad") files to the specified "INVALID FILE MOVE FOLDER". +' 2) Rename valid DOS-encoded file names and move renamed files to the specified "WEB FOLDER". +' 3) Move already-valid datasheet files to the specified "WEB FOLDER". +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' +'Hard-coded "names" file name and location. +Public Const NAMES_FILE_NAME = "DFWDS_NAMES.txt" +'Public Const NAMES_FILE_LOC = "C:\DFWDS" + +'Constants used as aliases for code readability. +Public Const DISPLAY_MESSAGES = "True" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const HIDE_MESSAGES = "False" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const MOVE_FILE = "True" 'Used, for example, by funcDSmoveRename to control whether the file is moved or renamed. +Public Const RENAME_FILE = "False" 'Used, for example, by funcDSmoveRename to control whether the file is moved or renamed. + +'Enumerated constants for the valid operation types. +Private Enum enOperation + OPINVALID = 0 'Invalid operation type (do nothing). + COUNTOP = 1 'Only count the files of various types ("bad", files to rename, valid datasheet files...). + LISTALL = 2 'List the files of various types ("bad", files to rename, valid datasheet files...) in the log file. + LISTBAD = 3 'List only the invalid ("bad") files in the log file. + LISTRENAME = 4 'List only the renamed valid datasheet files in the log file. + INPLACE = 5 'Rename the appropriate files in the same directory they are found. + WEBMOVE = 6 'Move the renamed and already-valid datasheet files to the specified "web move" directory. + End Enum +' +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + ' + 'Define the local variables. + Dim strDSfolderName As String 'Datasheet file folder. + Dim strBadLoc As String 'Invalid ("bad") files are moved to this location in certain operations. + Dim strWebLoc As String 'Web files ("good" and "renamed" files) are moved to this location in certain operations. + Dim strOperation As String 'Operation type (count, list, "in place" or "web move", etc. + Dim strLogFileName As String 'Log file name (only). + Dim strLogFileLoc As String 'Log file folder (only). + Dim strLogFileNameLoc As String 'Log file name and location. + Dim strLogFileLine As String 'Line for the log file. + Dim lCountRenameTotal As Long 'Number of datasheet files to be renamed. + Dim lCountInvalidTotal As Long 'Number of invalid datasheet files to be moved. + Dim lCountRenameGood As Long 'Number of datasheet files renamed that have been moved successfully. + Dim lCountInvalidGood As Long 'Number of invalid datasheet files that have been moved successfully. + Dim lCountAll As Long 'Total number of files in datasheet file directory. + Dim lCountValidTotal As Long 'Number of "good" datasheet files that do not need to be renamed. + Dim lCountValidGood As Long 'Number of "good" datasheet files that have been moved successfully. + Dim iLogFileHandle As Integer 'Log file number ("file handle"). + Dim dStartTime As Double 'Program start time. + Dim dEndTime As Double 'Program start time. + Dim strStartDate As String 'Date that the program is run. + Dim iOldMouse As Integer 'Store previous mouse state. + + On Error GoTo ErrorHandler + + 'Display program (splash) form. + frmSplash.Show + frmSplash.Refresh + + 'Get next valid file number (file + 'handle) for the log file. + iLogFileHandle = FreeFile + + 'Set start time. + dStartTime = Timer + + 'Initialize counts. + lCountRenameTotal = 0 + lCountInvalidTotal = 0 + lCountRenameGood = 0 + lCountInvalidGood = 0 + lCountValidTotal = 0 + lCountValidGood = 0 + lCountAll = 0 + + 'Check for "names" file and read values from the file. End the + 'program if there is a problem with the "names" file. + If Not (functionNamesFileReadOK(strDSfolderName, strLogFileName, strLogFileLoc, strBadLoc, strWebLoc, strOperation) = True) Then + End 'End the program. + End If + + 'Get starting date of program (for log file name and header) + 'and set full log file name based on the formatted date. + strStartDate = Format(Date$, "yyyy_mm_dd") 'Get starting date of program. + strLogFileName = strLogFileName & "_" & strStartDate & ".log" 'Get log file name with date. + + 'Open log file. + If (funcOpenLogFile(strLogFileName, strLogFileLoc, iLogFileHandle) = False) Then + Close #iLogFileHandle 'Close the log file. + Call subFileOpenMessage(strLogFileNameLoc) 'Display error message. + End 'Exit the program. + End If + + 'Write log file header. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Date: " & strStartDate & ", Time: " & Time$ + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + 'Call routine to process files in datasheet folder. + Call subProcessDSfolder(strOperation, strDSfolderName, strBadLoc, strWebLoc, strLogFileNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood, lCountValidTotal, lCountValidGood, _ + lCountAll) + + 'Write log file footer information and close the log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total files processed = " & lCountAll + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Bad files to be moved = " & lCountInvalidTotal & vbCrLf & _ + "Bad files successfully moved = " & lCountInvalidGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Files to be renamed = " & lCountRenameTotal & vbCrLf & _ + "Files successfully renamed = " & lCountRenameGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Valid (unchanged) files = " & (lCountValidTotal) & vbCrLf & _ + "Valid files successfully moved = " & (lCountValidGood) + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total good datasheet files = " & (lCountValidTotal + lCountRenameTotal) & vbCrLf & _ + "Good files successfully moved = " & (lCountValidGood + lCountRenameGood) + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + dEndTime = Timer 'Set end time. + strLogFileLine = "Elapsed time = " & Format(dEndTime - dStartTime, "##0.0") & " seconds" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + Close #iLogFileHandle + + 'Unload the program (splash) form. + Unload frmSplash 'Unload the network-copy program splash screen. + + End 'Exit program. + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Close #iLogFileHandle + MsgBox ("Error in ""Main"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End 'Exit program. +End Sub + +Public Function functionNamesFileReadOK(ByRef strDSfolderName As String, ByRef strLogFileName As String, _ + ByRef strLogFileLoc As String, ByRef strBadLoc As String, ByRef strWebLoc As String, _ + ByRef strOperation As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function checks for the presence of the "names" file holding the locations of the datasheet + 'file folder, the invalid file "move" folder, and the log file folder for the program as well as + 'the log file name. If the "names" file is found, this function reads lines from the file and puts + 'the values obtained in the appropriate variables that are returned, by reference, for use in other + 'routines. The validates the parameter names against the expected names for the appropriate lines + 'in the "names" folder, and for the folder values, validates the existence of the folders. The + 'function returns "True" if the "names" file is found and the parameter names and values read from + 'the names file can be validated against the expected values or the existence of the appropriate + 'folders. The function returns "False" if the "names" file cannot be found or read, if any of the + 'parameter names or values cannot be validated, or if there is any other problem in the function. + ' + 'NOTE: The log file name parameter value is validated outside of this function, when the log file + ' is first opened. + ' + ' Inputs: + ' All paramters are by-reference outputs whose values are read from the "names" file. + ' Outputs: + ' Error messages, log file entries. + ' Function return: The function returns "True" if the "names" file is found and can be + ' read and all of the parameters and values are appropriate. + ' strDSfolderName: Passes the name of the datasheet file folder by reference from + ' the validated value read from the "names" file. + ' strLogFileName: Passes the name of the log file by reference from the validated + ' value read from the "names" file. + ' strLogFileLoc: Passes the name of the log file folder by reference from the + ' validated value read from the "names" file. + ' strBadLoc: Passes the name of the invalid ("bad") file folder by reference from + ' the validated value read from the "names" file. + ' strWebLoc: Passes the name of the "Web" file folder by reference from + ' the validated value read from the "names" file. + ' strOperation: Passes the name of the operation by reference from + ' the validated value read from the "names" file. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strNamesFileLoc As String 'Location (folder) of the "names" file. + Dim strNamesFileNameLoc As String 'Name and location (folder) of the "names" file. + Dim strMessageString As String 'String for error message from reading "names" file lines. + Dim strParmName As String 'Parameter name read from the "names" file. + Dim strParmValue As String 'Parameter value read from the "names" file. + Dim strParmNameExpected As String 'Parameter value expected from the "names" file. + Dim iLineNumber As Integer 'Number of line read from the "names" file. + Dim iNamesFileHandle As Integer 'File number (file "handle") of the "names" file. + Dim objFSO As FileSystemObject 'File system object for "names" file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get next valid file number (file + 'handle) for the "names" file. + iNamesFileHandle = FreeFile + + 'Initialize. + strMessageString = "" 'Initialize as null (blank) string. + functionNamesFileReadOK = True 'Initialize as "all file entries read OK". + strDSfolderName = "" 'Set string to null. + strLogFileName = "" 'Set string to null. + strLogFileLoc = "" 'Set string to null. + strBadLoc = "" 'Set string to null. + strWebLoc = "" 'Set string to null. + strOperation = "" 'Set string to null. + + 'Set file name and location from hardcoded constants. + 'strNamesFileLoc = NAMES_FILE_LOC 'Set "names" file folder to defined location. + strNamesFileLoc = CurDir 'Set "names" file folder to defined location. + If Right$(strNamesFileLoc, 1) <> "\" Then strNamesFileLoc = strNamesFileLoc & "\" 'Add trailing backslash (if needed). + strNamesFileNameLoc = strNamesFileLoc & NAMES_FILE_NAME 'Add "names" file name to folder. + + 'Check for existence of "names" file folder. + If Not funcFolderExists(strNamesFileLoc, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strNamesFileLoc & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Check for existence of the "names" file. + If Not (objFSO.FileExists(strNamesFileNameLoc)) Then + 'File not found. Post error return, display + 'error message, and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The ""names"" file: " & strNamesFileNameLoc & " was not found!" & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Destroy the file system object (it is + 'not used later in the function). + Set objFSO = Nothing + + 'Open the "names" file for input (reading line by line). + Open strNamesFileNameLoc For Input As iNamesFileHandle + + 'Read lines of the "names" file and check parameter names and values. + For iLineNumber = 1 To 6 + 'Set expected parameter names. + If (iLineNumber = 1) Then strParmNameExpected = "DATASHEET FOLDER NAME" + If (iLineNumber = 2) Then strParmNameExpected = "INVALID FILE MOVE FOLDER" + If (iLineNumber = 3) Then strParmNameExpected = "LOG FILE NAME" + If (iLineNumber = 4) Then strParmNameExpected = "LOG FILE FOLDER" + If (iLineNumber = 5) Then strParmNameExpected = "WEB FOLDER" + If (iLineNumber = 6) Then strParmNameExpected = "OPERATION" + 'Get line of two comma-separated values and put into variables. + Input #iNamesFileHandle, strParmName, strParmValue + 'Trim the values read. + strParmName = Trim(strParmName) + strParmValue = Trim(strParmValue) + If (strParmName = strParmNameExpected) Then + 'Expected parameter name is found. + If ((iLineNumber = 3) Or (iLineNumber = 6)) Then + 'Log file partial name (line 3) or operation type (line 6). + 'No modification of parameter is required. + Else + 'The parameter is a location (folder) parameter. Add a trailing backslash, + 'if necessary, and check if the folder exists. + If Right$(strParmValue, 1) <> "\" Then strParmValue = strParmValue & "\" + 'Check if folder exists. + If Not funcFolderExists(strParmValue, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strParmValue & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + End If + Else + 'The parameter name read from the "names" file does not match the + 'expected value. Post error return, display error message, + 'and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The parameter read from the ""names"" file" & vbCrLf & _ + "does not match the expected value!" & vbCrLf & _ + "Parameter read: " & strParmName & vbCrLf & _ + "Parameter expected: " & strParmNameExpected & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Set parameter values to appropriate variables. + If (iLineNumber = 1) Then strDSfolderName = strParmValue + If (iLineNumber = 2) Then strBadLoc = strParmValue + If (iLineNumber = 3) Then strLogFileName = strParmValue + If (iLineNumber = 4) Then strLogFileLoc = strParmValue + If (iLineNumber = 5) Then strWebLoc = strParmValue + If (iLineNumber = 6) Then strOperation = strParmValue + Next iLineNumber + + 'Check for valid operation string. + If (funcGetOPnumber(strOperation) = 0) Then + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Invalid operation name =" & strOperation & vbCrLf & _ + "No file operations performed!" & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End If + + 'Close the "names" file. + Close #iNamesFileHandle + + Exit Function 'Exit the function (before the error handler) if no error. +ErrorHandler: + Close #iNamesFileHandle 'Close the "names" file. + Set objFSO = Nothing 'Destroy the file system object. + functionNamesFileReadOK = False 'Error return value. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcOpenLogFile(ByVal strLogFileName As String, ByVal strLogFileLoc As String, _ + ByVal iLogFileHandle As Integer) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function opens the log file specified by the passed file name and folder for append using the + 'passed file "handle". The function returns "True" if there is no problem opening the file, and + 'returns "False" if any problem occurs. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFullFileName As String + + On Error GoTo ErrorHandler + + 'Make sure the folder name includes a trailing "\", then create + 'full file name (file name including folder) and open the file + 'for append. + If Right$(strLogFileLoc, 1) <> "\" Then strLogFileLoc = strLogFileLoc & "\" + strFullFileName = strLogFileLoc & strLogFileName 'Create full file name (name with location). + Open strFullFileName For Append As iLogFileHandle 'Open log file for append. + funcOpenLogFile = True 'Return value indicating no problems opening the file. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcOpenLogFile = False 'Error value. + MsgBox ("Error in ""funcOpenLogFile"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subFileOpenMessage(ByVal strLogFileNameLoc As String) + '---------------------------------------------------------------------------------------------------- + 'Subroutine to display error message about opening the log file using the passed full log file name + '(the file name complete with its directory location). + '---------------------------------------------------------------------------------------------------- + ' + MsgBox ("Error opening log file: " & strLogFileNameLoc & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcFolderExists(ByVal strFolderName As String, ByVal bDisplayErrMsg As Boolean) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed folder exists, and "False" if it does not, or there is + 'any other problem with the function. The passed flag displays a "file not found" message if "True", + 'or skips the message if "false" (for example, if a calling routine has its own error message). + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Make sure the folder name includes a trailing "\". + If Right$(strFolderName, 1) <> "\" Then strFolderName = strFolderName & "\" + + 'Check whether the folder exists. + If Not objFSO.FolderExists(strFolderName) Then + funcFolderExists = False 'Return value for "folder not found". + If (bDisplayErrMsg) Then + 'Display error message if the flag is "True". + MsgBox ("Folder not found: " & strFolderName & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End If + Else + funcFolderExists = True 'Return value for "folder found". + End If + + Set objFSO = Nothing 'Destroy file system object. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcFolderExists = False 'Error value. + Set objFSO = Nothing 'Destroy file system object. + MsgBox ("Error in ""funcFolderExists"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subProcessDSfolder(ByVal strOperation As String, ByVal strDSfolderName As String, ByVal strDSbadLocation As String, _ + ByVal strWebLoc As String, ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer, ByRef lCountInvalidTotal As Long, _ + ByRef lCountRenameTotal As Long, ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long, _ + ByRef lCountValidTotal As Long, ByRef lCountValidGood As Long, ByRef lCountAll As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the datasheet (and possibly other) files in the passed folder. The subroutine + 'initializes counts, writes a header to the log file specified by the passed log file name and location, + 'and performs a directory listing of the passed folder, processing each file name through using + 'the "subProcessDSfile" subroutine to determine whether the file is an invalid ("bad") datasheet file. + 'Depending on the passed "operation", the subroutine moves the "bad" files to the passed "bad" file + 'location, renames and moves the files with valid DOS-encoded datasheet file names to the passed "Web" + 'folder, and also moves the files with valid datasheet names that do not need to be renamed to the + 'passed "Web" folder. All of these actions (or "list" or "count" operations and/or data) are logged to + 'the log file. + ' + ' Inputs: + ' strOperation: Datasheet file operation ("list" or "count" type operations, "in place" rename + ' or "web move" for valid and renamed datasheet files). + ' strDSfolderName: Source datasheet file folder location. + ' strDSbadLocation: Directory location where invalid ("bad") files are moved. Invalid files include + ' non-text files and files with names that do not match the format for the Dataforth + ' website. + ' strWebLoc: Directory location where valid and renamed datasheet files are moved. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountValidTotal: Passes initial count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes initial count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountAll: Passes initial count of all files found in the datasheet folder to + ' the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid ("bad") datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid ("bad") datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidTotal: Passes count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountAll: Passes the count of all files found in the datasheet file folder + ' back to the calling routine by reference for status displays, etc. + ' Also used, on first call, to pass the initial count from the calling + ' routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFileName As String + Dim strFullFileName As String + Dim strDirSpec As String + + On Error GoTo ErrorHandler + + 'Initialize. + lCountInvalidTotal = 0 + lCountRenameTotal = 0 + lCountInvalidGood = 0 + lCountRenameGood = 0 + lCountValidTotal = 0 + lCountValidGood = 0 + lCountAll = 0 + + 'Set Dir$ function specification (directory path and search criteria). + 'NOTE: Search criteria is "all files", rather than just "text files" + ' since text files are validated later as part of the specific + ' datasheet file validation process. + If Right$(strDSfolderName, 1) <> "\" Then + strDirSpec = strDSfolderName & "\*.*" 'Add trailing backslash (if needed) and search for any file. + Else + strDirSpec = strDSfolderName & "*.*" 'Add search for any text file. + End If + 'strFileName = Dir$(strDirSpec, vbNormal) + + 'Loop through each file in the folder + 'Do While (strFileName <> "") + Do + 'Loop through all matching files in directory. + 'strFileName = Dir$ + strFileName = Dir$(strDirSpec, vbNormal) + If (strFileName <> "") Then + Call subProcessDSfile(strOperation, strFileName, strDSfolderName, strDSbadLocation, strWebLoc, _ + strDSlogNameLoc, iLogFileHandle, lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood, _ + lCountValidTotal, lCountValidGood) + lCountAll = lCountAll + 1 'Increment total count. + frmSplash.lblFileCount.Caption = lCountAll + frmSplash.lblCurrentFile.Caption = strFileName + frmSplash.lblFileCount.Refresh + frmSplash.lblCurrentFile.Refresh + Else + Exit Do + End If + Loop + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfolder"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subProcessDSfile(ByVal strOperation As String, ByVal strDSFileName As String, ByVal strDSfolderName As String, _ + ByVal strDSbadLocation As String, ByVal strDSwebFolderName As String, ByVal strDSlogNameLoc As String, _ + ByVal iLogFileHandle As Integer, ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long, _ + ByRef lCountValidTotal As Long, ByRef lCountValidGood As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the passed file name. If it is determined to be an invalid name for the Dataforth + 'website, the file is moved to the passed directory location and this action is recorded in a log file + 'whose name and location is also passed as a parameter. If the file name matches the format of "encoded" + 'datasheet file names from the DOS test programs, the file is renamed to the appropriate "unencoded" + 'datasheet file name and this action is also recorded to the specified log file. The subroutine posts + 'error messages for problems that may be encountered during file processing, and passes file counts + '(total files found to be renamed or moved, files successfully rename or moved) to the calling routine. + ' + ' Inputs: + ' strOperation: Datasheet file operation ("list", "count", "in place", "web move", etc.). + ' strDSfileName: Datasheet file name. + ' strDSbadLocation: In certain operations, this is the directory location where invalid ("bad") + ' files are moved. Invalid files include non-text files and files with names + ' that do not match the format for the Dataforth website. + ' strDSwebFolderName: In certain operations, this is the directory location where valid or renamed + ' files are moved. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountValidTotal: Passes initial count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes initial count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidTotal: Passes count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strWorkOrderNum As String 'Work order number. + Dim strFullFileName As String 'Full file name (including extension). + Dim strFileNameOnly As String 'File name (only). + Dim iDashLoc As Integer 'Dash location in file name (only) string. + Dim iFNOlength As Integer 'Length of file name (only) string. + Dim strWOdecoded As String 'Work order number. + + On Error GoTo ErrorHandler + + 'Get uppercase-only version of the full file name. + 'This is necessary for later processing of the + 'datasheet files (including determining whether + 'they are validly-named datasheet files). + strFullFileName = UCase$(strDSFileName) + + 'Get the file name (only). This should be the (encoded + 'or unencoded) module serial number. Note that the + 'function requires a full file name already in + 'all-UPPERCASE. + strFileNameOnly = funcGetFileNameOnly(strFullFileName) + + 'Check for text file. + If (strFileNameOnly = "") Then + 'Not a text file (null return from funcGetFileNameOnly). + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-text file. + End If + + 'Check for valid dash location (and/or existence) and a valid dash number. + iDashLoc = funcGetDashLoc(strFileNameOnly) 'Get dash location. + + 'Check for valid location. + If Not (funcGetDashLoc(strFileNameOnly) > 0) Then + 'Dash (or dash number) is not valid. + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + + 'Parse work order# (characters to the left of + 'the dash) from the serial number string. + strWorkOrderNum = Left$(strFileNameOnly, iDashLoc - 1) + + If (funcIsAllNumbers(strWorkOrderNum) = True) Then + 'Work order number string is all numbers, + 'check for leading "0". + If (Left$(strWorkOrderNum, 1) = "0") Then + 'Leading "0" in all-numeric work order number. Work order number is not valid. + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + Else + 'Valid work order number. Move file to "web folder". + lCountValidTotal = lCountValidTotal + 1 'Increment already-valid file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSwebFolderName, strDSlogNameLoc, iLogFileHandle) Then + lCountValidGood = lCountValidGood + 1 'Increment already-valid files moved successfully count. + End If + End If + Else + 'Work order string is not all numbers. Check if + 'it is matches the format of a DOS-encoded work + 'order number. + If (funcISrenameWO(strWorkOrderNum) = True) Then + 'DOS-encoded work order number. Rename file + 'to unencoded datasheet file name. + lCountRenameTotal = lCountRenameTotal + 1 'Increment "renamed" file count. + If funcDSmoveRename(RENAME_FILE, strFullFileName, strDSfolderName, "", strDSlogNameLoc, iLogFileHandle) Then + 'File successfully renamed in place. Move to "web folder". + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSwebFolderName, strDSlogNameLoc, iLogFileHandle) Then + lCountRenameGood = lCountRenameGood + 1 'Increment "renamed" file processed correctly ("good") count. + End If + End If + Else + 'Not a DOS-encoded work order number. Work order number is not valid. + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + End If + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcGetFileNameOnly(ByVal strFullFileName As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned + 'if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem (such as a blank file name passed to the function), a null string + 'is returned. + ' + 'NOTE: The passed full file name must be in all-UPPERCASE for the ".TXT" check to work. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strFullFileName) 'Get length of the full file name. + strSerial = Left$(strFullFileName, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcGetFileNameOnly = strSerial + Else + funcGetFileNameOnly = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcGetFileNameOnly = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcGetFileNameOnly = "" 'Error value. + MsgBox ("Error in ""funcGetFileNameOnly"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Function funcIsAllNumbers(ByVal strTestString As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'Function that checks whether the passed string consists of only numerical characters. The function + 'returns "True" if each character in the string is a number, and "False" if any character is not + 'a number or if there is some other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strChar As String + Dim iDx As Integer + + On Error GoTo ErrorHandler + + 'Initialize to "all numbers" value. + funcIsAllNumbers = True + + If (strTestString = "") Then + 'Invalid Work Order number string (null string). + funcIsAllNumbers = False 'Set "not all numbers" value. + Else + For iDx = 1 To Len(strTestString) 'Loop from 1st character to last character of string. + 'See if the next character is a non-number. + strChar = Mid$(strTestString, iDx, 1) 'Get next character. + If ((strChar < "0") Or (strChar > "9")) Then 'Character is not "0" through "9". + funcIsAllNumbers = False 'Set "not all numbers" value. + Exit For 'Exit the loop (no need to continue after first non-number). + End If + Next iDx + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsAllNumbers = False 'Error ("not all numbers") value. + MsgBox ("Error in ""funcIsAllNumbers"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetDashLoc(ByVal strFileNameOnly As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the dash ("-") location in the passed file name (only) string. It returns + 'an error value of "0" if no dash is found, or more than one dash is found, if there are more + 'than one characters after the dash, and if any of the characters after the dash are not a + 'number, or if there are any other problems in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + Dim strDashNum As String 'Dash number string. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strFileNameOnly) 'Length of file name (only) string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strFileNameOnly, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strFileNameOnly, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end (dash number + 'more than two characters, or less than one). + funcGetDashLoc = 0 'Error value (invalid dash). + Else + 'Dash number is one or two characters. Get for an all-number dash number. + strDashNum = Mid$(strFileNameOnly, iDashLocL + 1, iSTRlength - iDashLocL) + If (funcIsAllNumbers(strDashNum) = True) Then + 'Dash number is all numbers. + funcGetDashLoc = iDashLocL 'Good value (valid dash). + Else + 'Dash number is not valid (not all numbers). + funcGetDashLoc = 0 'Error value (invalid dash). + End If + End If + Else + 'More than one dash in the serial string. + funcGetDashLoc = 0 'Error value (invalid dash). + End If + + Exit Function 'Exit before error handler. +ErrorHandler: + funcGetDashLoc = 0 'Error (not valid) value. + MsgBox ("Error in ""funcIsValidDash"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDecodeWOchar(ByVal strWOnum As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns a two-character string decoded from the first character of the + 'passed work order number string. If the first character is "A" through "J", the + 'function returns "10" through "19", respectively, which represents the values that + 'are encoded in valid DOS-encoded datasheet file names. If the first character is + 'not "A" or "J" or a letter in between, or if there is some problem in the function, + 'the function returns a null string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strFirstChar As String 'First character in passed work order number string. + + On Error GoTo ErrorHandler + + If (strWOnum = "") Then + 'Null string, return error value (null string). + funcDecodeWOchar = "" 'Error value. + Else + 'String has at least one character, check for "A" through "J". + strFirstChar = Left$(strWOnum, 1) 'Get first character of passed work order number. + If (strFirstChar = "A") Then + funcDecodeWOchar = "10" 'Decode of first character. + ElseIf (strFirstChar = "B") Then + funcDecodeWOchar = "11" 'Decode of first character. + ElseIf (strFirstChar = "C") Then + funcDecodeWOchar = "12" 'Decode of first character. + ElseIf (strFirstChar = "D") Then + funcDecodeWOchar = "13" 'Decode of first character. + ElseIf (strFirstChar = "E") Then + funcDecodeWOchar = "14" 'Decode of first character. + ElseIf (strFirstChar = "F") Then + funcDecodeWOchar = "15" 'Decode of first character. + ElseIf (strFirstChar = "G") Then + funcDecodeWOchar = "16" 'Decode of first character. + ElseIf (strFirstChar = "H") Then + funcDecodeWOchar = "17" 'Decode of first character. + ElseIf (strFirstChar = "I") Then + funcDecodeWOchar = "18" 'Decode of first character. + ElseIf (strFirstChar = "J") Then + funcDecodeWOchar = "19" 'Decode of first character. + Else + 'Not "A" through "J" + funcDecodeWOchar = "" 'Error value. + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcDecodeWOchar = "" 'Error value. + MsgBox ("Error in ""funcDecodeWOchar"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcISrenameWO(ByVal strWOnumber As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed work order number matches the format of a DOS-encoded + 'work order number (for work orders above the value of "99,999"). A DOS-encoded work order number + 'will be five characters long, start with "A" through "J", and have all numbers for the remaining + 'characters. The function will return "False" if any of these conditions are not true, or there is + 'any other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLastFour As String + Dim strFirstOne As String + + On Error GoTo ErrorHandler + + If (Len(strWOnumber) <> 5) Then + 'Not five characters long. + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strFirstOne = UCase$(Left$(strWOnumber, 1)) + If ((strFirstOne < "A") Or (strFirstOne > "J")) Then + 'First character not "A" through "J". + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strLastFour = Right$(strWOnumber, 4) + If (funcIsAllNumbers(strLastFour) = True) Then + funcISrenameWO = True 'Set "valid rename string" value. + Else + 'Last four characters not all numberss. + funcISrenameWO = False 'Set "not a valid rename string" value. + End If + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcISrenameWO = False 'Error value (not valid "rename" string). + MsgBox ("Error in ""funcISrenameWO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDSmoveRename(ByVal bMoveFile As Boolean, ByRef strDSFileName As String, ByVal strDSfolderName As String, _ + ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer) As Boolean + '------------------------------------------------------------------------------------------------------------- + 'Function that moves or renames the file specified by the passed file name and datasheet file folder. If the + 'move/rename parameter ("bMoveFile") is "True", the file is moved to the directory specified by the + 'passed "move location" folder name. If the parameter is "False", the file is renamed from the DOS-encoded + 'name to the unencoded datasheet file name. In both cases, the "move" or "rename" is accomplished by copying the + 'file to the new name or location, and then deleting the old file if nothing has gone wrong. All actions, + 'including successful moves or renames, unsuccessful file copies, or unsuccessful file deletions, are + 'recorded in a log file whose name and location, as well as its file number (file "handle"), are passed + 'as parameters. The function returns "True" if there are no problems, and "False" if there are any problems. + 'The function also returns (by reference) the new datasheet file name of renamed files. + ' + 'NOTE: Since the existence of all of the relevant directories is verified by one of the calling routines + ' directory checking is not repeated here to save program time (since this function is called for + ' every relevant file). + ' + ' Inputs: + ' bMoveFile: This parameter is "True" to move the specified file to the "move" + ' folder or "False" to rename the specified file from the + ' DOS-encoded work order number (for values above "99,999") to the + ' unencoded work order number (file name matching the module serial + ' number contained within the datasheet file). + ' strDSFileName: Full file name of the file to be moved (includes file extension + ' but not folder location). + ' strDSfolderName: Datasheet folder location. + ' strDSmoveLocation: Directory location where the file is to be moved. + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' iLogFileHandle: File "handle" (file number) for log file. + ' Outputs: + ' Error messages, log file entries. + ' strDSFileName: Full file name of the renamed datasheet file (includes file extension + ' but not folder location). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLogFileLine As String 'String for a line of information for the log file. + Dim strRenameFileName As String 'Full file name (name and extension) for the renamed (unencoded) datasheet file name. + Dim strDSFileNameLoc As String 'Full file name (name and extension) and folder of the file in the datasheet folder. + Dim strRenameFileNameLoc As String 'Full file name (name and extension) and folder for the renamed (unencoded) datasheet file name. + Dim strRenameFirstChars As String 'First character of file to be renamed, or (decoded) first two characters of renamed file. + Dim iLenFullFileName As Integer 'Length of the full file name of the file to be renamed. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + + 'Initialize function return. + funcDSmoveRename = False 'Initialize to bad return (set to good at end if there are no problems). + + 'Initialize strings to null. + strLogFileLine = "" + strRenameFileName = "" + strDSFileNameLoc = "" + strRenameFileNameLoc = "" + strRenameFirstChars = "" + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Create the full file name and location from the full file + 'name and the folder location. First, add a trailing + 'backslash, if needed, to the folder location. + If Right$(strDSfolderName, 1) <> "\" Then strDSfolderName = strDSfolderName & "\" + strDSFileNameLoc = strDSfolderName & strDSFileName + + 'If the file needs to be renamed, create the full "rename" file name + '(file name and extension) from the original DOS-encoded name, then + 'create the full name/location (file name and folder location). + If Not (bMoveFile) Then + 'File to be renamed. Decode first character of full file name. + strRenameFirstChars = Left$(strDSFileName, 1) 'Get first character of file to be renamed. + iLenFullFileName = Len(strDSFileName) 'Get the length of the full file name of the file to be renamed. + 'Use the "decode work order character" function to decode the first character of the full + 'file name of the file to be renamed (note, the function name implies the passed string + 'is the work order number only, but since the function only uses the first character of + 'the string, it also works for the full file name). + strRenameFirstChars = funcDecodeWOchar(strDSFileName) 'Get decoded first two characters of full file name. + 'Create the renamed file name, by combining the new decoded characters with the characters of the full + 'datasheet file name to be renamed, but skipping the first character. + strRenameFileName = Right$(strDSFileName, iLenFullFileName - 1) 'Get full file name minus the first character. + strRenameFileName = strRenameFirstChars & strRenameFileName 'Create full rename file name by adding decoded characters. + strRenameFileNameLoc = strDSfolderName & strRenameFileName 'Create full rename file name/location by adding folder. + 'NOTE: This is the same folder as the original + ' datasheet file. + strDSFileName = strRenameFileName 'Return renamed datasheet file name. + End If + + 'Create "could not copy" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the CopyFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "copy good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not copy" message. + strLogFileLine = "Could not copy file: " & strDSFileNameLoc & " to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not copy file: " & strDSFileNameLoc & " to: " & strRenameFileName + End If + + 'Copy the file in the datasheet folder. For moves, copy to the "move" directory. + 'For rename, copy to a new name in the same folder. File copy parameters: + 'source (full file name/loc), destination (folder + 'only or full (rename) file name/loc), "True" for + 'overwrite if a file of same name already exists + 'in the destination. + If (bMoveFile) Then + 'Move invalid file. Start by copying to new folder location. + Call objFSO.CopyFile(strDSFileNameLoc, strDSmoveLocation, True) + Else + 'Rename DOS-encoded datasheet file. Start by copying to name in same folder. + Call objFSO.CopyFile(strDSFileNameLoc, strRenameFileNameLoc, True) + End If + + 'Create "could not delete" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the DeleteFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "delete good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not delete" message. + strLogFileLine = "Could not delete file: " & strDSFileNameLoc & " after copy to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not delete file: " & strDSFileNameLoc & " after copy to: " & strRenameFileName + End If + + 'Delete the invalid file in the datasheet folder. + 'File delete parameters: full file/loc, "True" + 'for "force" (ignore read-only). + Call objFSO.DeleteFile(strDSFileNameLoc, True) + + 'Since there were no problems to this point (no jump to the error handler), + 'create "successfully moved" or "successfully renamed" message and write + 'the message to the log file. + If (bMoveFile) Then + strLogFileLine = "Moved file: " & strDSFileNameLoc & " to: " & strDSmoveLocation + Else + strLogFileLine = "Renamed file: " & strDSFileNameLoc & " to: " & strRenameFileName + End If + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + funcDSmoveRename = True 'Set Good function return. + + Set objFSO = Nothing 'Destroy file system object. + + Exit Function ' Exit before error handler. +ErrorHandler: + Print #iLogFileHandle, strLogFileLine 'Write previously-generated error message to log file. + Set objFSO = Nothing 'Destroy file system object. + 'NOTE: Since this function processes many files, errors should be posted (only) to the log + ' file, NOT to the screen. Therefore, the following two lines (single line of code) + ' are (is) commented out. + 'MsgBox ("Error in ""funcDSmoveRename"" = " & Err.Description & vbCrLf & vbCrLf & _ + ' "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetOPnumber(ByVal strOPname As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the appropriate enumerated operation number from the passed + 'operation string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iReturn As Integer + + On Error GoTo ErrorHandler + + If (strOPname = "COUNT") Then + iReturn = 1 + ElseIf (strOPname = "LISTALL") Then + iReturn = 2 + ElseIf (strOPname = "LISTBAD") Then + iReturn = 3 + ElseIf (strOPname = "LISTRENAME") Then + iReturn = 4 + ElseIf (strOPname = "INPLACE") Then + iReturn = 5 + ElseIf (strOPname = "WEBMOVE") Then + iReturn = 6 + Else + iReturn = 0 'Error value. + MsgBox ("Error in ""funcGetOPnumber"" = " & vbCrLf & _ + "Invalid operation = " & strOPname & vbCrLf & _ + "Function return = " & iReturn & vbCrLf), vbCritical + End If + + funcGetOPnumber = iReturn 'Set function return. + + Exit Function ' Exit before error handler. +ErrorHandler: + iReturn = 0 'Error value. + funcGetOPnumber = iReturn 'Set function return. + MsgBox ("Error in ""funcGetOPnumber"" = " & Err.Description & vbCrLf & _ + "Function return = " & iReturn & vbCrLf), vbCritical +End Function + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.vbp new file mode 100644 index 0000000..540b885 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\Windows\SysWOW64\MSSTDFMT.DLL#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao350.dll#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; tabctl32.ocx +Module=A_Main; DFWDS.bas +Form=frmSplash.frm +Startup="Sub Main" +HelpFile="" +Title="DFWDS" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.vbw new file mode 100644 index 0000000..f62f99f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C diff --git a/projects/dataforth-dos/dfwds-research/source/Release/DFWDS_NAMES.txt b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS_NAMES.txt new file mode 100644 index 0000000..cc4dab1 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/DFWDS_NAMES.txt @@ -0,0 +1,80 @@ +DATASHEET FOLDER NAME,X:\Test_Datasheets +INVALID FILE MOVE FOLDER,X:\Bad_Datasheets +LOG FILE NAME,DFWDS +LOG FILE FOLDER,X:\Datasheets_Log +WEB FOLDER,X:\For_Web +OPERATION,WEBMOVE + +Last updated: 2015-06-08 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +----------- +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +------------ +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +----------- +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +------------ +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +----------- +OPERATION: This parameter controls the operation of the program, and +can only be one of the values described below: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/Release/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/Release/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.bas new file mode 100644 index 0000000..4a1466d --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.bas @@ -0,0 +1,501 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2014_09_24" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/24 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = this file, main code module. +' VB FORMS: frmDBselect.frm = form to select directory and .DAT file for model database. +' frmDATAselect.frm = form to select .DAT file for stored model datasheet data and print +' text file datasheets. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/24 PWR Initial version. +' +' ------------------------------------------------------------------------------------------------------------------------------------- + +'---------------------------------------------------------------------------------------------------- +' Hard-coded values. +'---------------------------------------------------------------------------------------------------- +Public Const PRINTSHEET_SUBDIR = "PRINT" ' Hardcoded printed datasheet directory (below folder with .DAT files). +Public Const NUMPTS = 5 ' Hardcoded number of points for accuracy/linearity measurements. +Public Const NUMTESTS = 20 ' Hardcoded maximum array index (# of stored tests) for STATUS (strTestDATSTRING) and other arrays. + +' Global variables. +Public strDBFILEname As String ' Global variable to hold database (.DAT) file name. +Public strDBFILEfolder As String ' Global variable to hold database (.DAT) file folder. +Public strDATFILEname As String ' Global variable to hold stored datasheet data (.DAT) file name. +Public strDATFILEfolder As String ' Global variable to hold stored datasheet data (.DAT) file folder. +Public iFileCount As Integer ' Count of number of text datasheet files "printed". +Public iDupCount As Integer ' Count of number of text datasheet files "printed" over an existing file. +Public bDisplayMessages As Boolean ' Flag, "True" to display error messages in various functions and subroutines. +Public bPrintFailingUnits As Boolean ' Flag, "True" to also print text log files from failing units. + +' Global arrays. +Public strTestNAMES(1 To NUMTESTS) As String ' Global array for the Final Test test names. +Public strTestUNITS(1 To NUMTESTS) As String ' Global array for the Final Test test units. +Public strTSPEC(1 To NUMTESTS) As String ' Global array for the Final Test test limits strings for printed datasheet. +Public strMODNAME As String ' Global variable for module model name: "SCM5B30-1419", for example. +Public strSerialNumber As String ' Global variable for work order-serial number (collectively: Serial Number). +Public strDATETESTED As String ' Global variable for date tested. +' Global array for the Final Test test status read from the .DAT file (this includes the "PASS" or "FAIL" status, +' test results, and the number of decimal points to display). +Public strTestDATSTRING(1 To NUMTESTS) As String +' Global arrays for the Accuracy/Linearity test data read from the .DAT file. +Public strTSIM(1 To 5) As String ' Input value during acc/lin test (index is meas. #). +Public strOUTCALC(1 To 5) As String ' Calculated output value during acc/lin test (index is meas. #). +Public strOUTMEAS(1 To 5) As String ' Measured output value during acc/lin test (index is meas. #). +Public strERROROUT(1 To 5) As String ' Calculated output error during acc/lin test (index is meas. #). +Public strACCSTAT(1 To 5) As String ' PASS or FAILED status string during acc/lin test (index is meas. #). +' Global variable for data read from the datalog (.DAT) file. +Public sLOWV As Single ' Obsolete read value from datalog file. +Public sHIGHV As Single ' Obsolete read value from datalog file. +Public sTOTLRESPEC As Single ' Obsolete read value from datalog file. + + +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + + On Error GoTo ErrorHandler + + ' Initialize Final Test names and units for tests and stored + ' values for data read from datalog and database files. + + '------------------------------------------------------ + ' Display program screen. + ' NOTE: if screen is shown modal, it will NOT show up + ' in the taskbar nor be found by clicking alt-tab to + ' select open programs! + '------------------------------------------------------ + + 'frmDBselect.Show vbModal ' Show screen (modal). + frmDSfiles.Show ' Show screen (nonmodal). + + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + + MsgBox ("Error in ""Main"" subroutine = " & Err.Description) + +End Sub + +Public Function funcMakePathFromFolder(ByVal strSubfolderName As String) As Boolean + '------------------------------------------------------------------------------------- + ' Function to create directories (folders) as needed, based on the passed parameter. + ' + ' NOTE: The "strSubfolderName" parameter is assumed to be a complete path, including + ' drive letter. This subroutine does not handle other path forms, such as + ' those starting with a "\\" (as in "\\fileserver\") and will generate an + ' error message and return "False" if an invalid folder name is passed. + '------------------------------------------------------------------------------------- + Dim arTemp() As String ' Dynamic array to store parsed values from "Split" function. + Dim iArrayIndex As Long ' String-array index. + Dim strFolder As String ' (Re)combined folder name string, concatenated piece by piece from original. + Dim objFSO As New Scripting.FileSystemObject ' New instance of FileSystemObject. + + On Error GoTo ErrorHandler + + 'strFolder = sFolderRoot & "\" ' Initialize to root. + 'strFolder = Left$(strSubfolderName, 2) & "\" ' Initialize to drive letter and backslash. + strFolder = "" ' Initialize to drive letter and backslash. + + arTemp = Split(strSubfolderName, "\") ' Split "full" folder name to array of strings at each backslash. + + ' For each split string (folder name) check if folder already exists. Lower and upper bounds of array are determined + ' by the array itself (the number of strings depends on the contents of the "full" folder name (complete path). The + ' initial string should be the drive name. If the folder does not exist, it is created. The "combined" folder name is + ' then re-combined by adding a backslash and then the next string in the array (the next folder name). + For iArrayIndex = LBound(arTemp) To UBound(arTemp) + strFolder = strFolder & arTemp(iArrayIndex) & "\" + If Not objFSO.FolderExists(strFolder) Then + Call objFSO.CreateFolder(strFolder) + End If + Next iArrayIndex + Set objFSO = Nothing + + funcMakePathFromFolder = True ' Set function return before exit. + + Exit Function ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Set objFSO = Nothing + funcMakePathFromFolder = False ' Set function error return. + MsgBox ("Error in function ""funcMakePathFromFolder"" = " & Err.Description & vbCrLf & _ + "Folder name = " & strFolder & vbCrLf & _ + "Function returning ""False""!") +End Function + +Public Sub subInitTestNAMES() + ' This subroutine initializes the "strTestNAMES" global array with the + ' names of the tests for the text data file. + ' + Dim iIndex As Integer + + On Error GoTo ErrorHandler + + strTestNAMES(1) = "Supply Current" + strTestNAMES(2) = "Supply Curr. w/ EXC Load" + strTestNAMES(3) = "Exc. Current @ -f.s." + strTestNAMES(4) = "Exc. Current @ +f.s." + strTestNAMES(5) = "" + strTestNAMES(6) = "" + strTestNAMES(7) = "Excitation Voltage" + strTestNAMES(8) = "EXC.Load Regulation" + strTestNAMES(9) = "Output Reg. w/ EXC Load" + strTestNAMES(10) = "Excitation Current Limit" + strTestNAMES(11) = "Linearity" + strTestNAMES(12) = "Accuracy" + strTestNAMES(13) = "Lead Resistance Effect" + strTestNAMES(14) = "Power Supply Sensitivity" + strTestNAMES(15) = "Input Resistance" + strTestNAMES(16) = "Open Thermocouple Resp." + strTestNAMES(17) = "Frequency Response" + strTestNAMES(18) = "Step Response" + strTestNAMES(19) = "Output Noise" + strTestNAMES(20) = "Chg. in Iout w/ Max Load" + + Exit Sub ' Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subInitTestNAMES"" = " & Err.Description), vbCritical +End Sub + +Public Function funcIsMatchingString(ByVal strFirst As String, ByVal strSecond As String) As Boolean + ' This function returns "True" if the "trimmed" values of the two strings that are passed + ' to it match. + ' + On Error GoTo ErrorHandler + + If (Trim(strFirst) = Trim(strSecond)) Then + funcIsMatchingString = True ' Strings match. + Else + funcIsMatchingString = False ' Strings do not match. + End If + + Exit Function ' Exit before error handler. + +ErrorHandler: + funcIsMatchingString = False ' Error value. + MsgBox ("Error in ""funcIsMatchingString"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Public Sub subProcessDatasheetFiles(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim objFSO As FileSystemObject + Dim objFolder As Folder + Dim objFile As File + Dim NextRow As Long + Dim iCount As Integer + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject. + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get the folder. + Set objFolder = objFSO.GetFolder(strFolderName) + + 'If the folder does not contain files, exit the sub. + 'If (objFolder.Files.Count = 0) Then + ' MsgBox "No files were found...", vbExclamation + ' Exit Sub + 'End If + + iCount = 0 'Initialize. + + 'Loop through each file in the folder + For Each objFile In objFolder.Files + frmDSfiles.lstInvalidDS.AddItem objFile.Name + iCount = iCount + 1 + frmDSfiles.txtInvalidCount.Text = iCount + Next objFile + + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDatasheetFiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Public Sub subDirList(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim strFileName As String + Dim strDirSpec As String + Dim iCountInvalid As Integer + Dim iCountRename As Integer + + On Error GoTo ErrorHandler + + 'Initialize. + iCountInvalid = 0 + iCountRename = 0 + frmDSfiles.lstInvalidDS.Clear + + 'Set Dir$ function specification (directory path and search criteria). + strDirSpec = strFolderName & "\*.txt" + strFileName = Dir$(strDirSpec, vbNormal) + + 'If the folder does not contain files, exit the sub. + 'If (strFileName = "") Then + ' MsgBox "No files were found...", vbExclamation + ' Exit Sub + 'End If + + 'Loop through each file in the folder + Do While (strFileName <> "") + strFileName = Dir$ + If (strFileName <> "") Then + frmDSfiles.lstInvalidDS.AddItem strFileName + iCount = iCount + 1 + End If + Loop + frmDSfiles.txtInvalidCount.Text = iCountInvalid + frmDSfiles.txtRenameCount.Text = iCountRename + frmDSfiles.Refresh + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDirList"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcParseFileName(ByVal strFullFileName) As String + 'This function parses out the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned in + 'uppercase if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem, a null string is returned. + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + strSerial = UCase$(strFullFileName) 'Set serial number string to full file name in uppercase. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strSerial) 'Get length of the full file name. + strSerial = Left$(strSerial, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcParseFileName = strSerial + Else + funcParseFileName = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcParseFileName = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcParseFileName = "" 'Error value. + MsgBox ("Error in ""funcParseFileName"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcIsDashValid(ByVal strSerial) As String + 'This function checks for a valid dash ("-") in the passed (module) serial string. + 'For the dash to be valid, there must be a dash in the string, there must be only + 'one dash in the string, and the dash must be the second or third character from + 'the end (right side) of the string. The function returns "True" if there is a + 'valid (single, correctly located) dash, and "False" otherwise, including when + 'there is an error in the function. + ' + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strSerial) 'Length of serial string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strSerial, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strSerial, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the serial string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end. + funcIsDashValid = False 'Error value (invalid dash). + Else + funcIsDashValid = True 'Good value (valid dash). + End If + Else + 'More than one dash in the serial string. + funcIsDashValid = False 'Error value (invalid dash). + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsDashValid = False 'Error value (invalid dash). + MsgBox ("Error in ""funcIsDashValid"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcSNparse(ByVal strFullFileName As String, ByRef strWorkOrderNum As String, ByRef strDashNum As String) As Boolean + 'Function that receives the name of the datasheet sheet file and parses out both the work order number and + 'dash number from the complete module serial number contained in the file name, and returns them (by reference) + 'as the "strWorkOrderNum" and "strDashNum" parameters. The function returns "True" if there is no error and + 'work order and dash numbers could be successfully parsed, and "False" if there is any error or problem. + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iCharLoc As Integer 'Character location in file name string. + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + 'Get serial number (file name) string from full file name. + strSerial = funcParseFileName(strFullFileName) + + 'Validate serial number, and parse if valid. + If (strSerial <> "") Then + 'Valid serial number. Perform further serial number validation. + If (funcIsDashValid(strSerial) = True) Then + 'Serial number contains a single, valid dash. + + 'Get length of serial number + iSTRlength = Len(strSerial) + + 'Location of dash characters (from start (left) of string) when searched from the left. + iCharLoc = InStr(strSerial, "-") + + 'Parse work order# (characters to the left of the dash) from the serial number string. + strWorkOrderNum = Left$(strSerial, iCharLoc - 1) + + 'Parse the dash# (characters to the right of the dash) from the serial number string. + strDashNum = Mid$(strSerial, iCharLoc + 1, iSTRlength - iCharLoc%) + + Else + 'Invalid dash number (missing, duplicate, or in wrong location) in serial number. + funcSNparse = False ' Error value. + Exit Function 'Exit function on erroneous file name. + End If + Else + 'Not a valid datasheet file name. + funcSNparse = False ' Error value. + Exit Function 'Exit function on erroneous file name. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcSNparse = False ' Error value. + MsgBox ("Error in ""funcSNparse"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + + + + + + +#If 0 Then +Function ISPOSNUMBER%(TESTVALUE$) + 'Function that checks if the passed string is a positive number (entirely numerical) + 'or is a string (at least one non-numerical character). Returns "1" for a positive + ' number or "0" anything else + ISPOSNUMBER% = 1 'Initialize to function return for numerical string + N% = Len(TESTVALUE$) 'Get length of passed string + Do Until N% = 0 + TVC$ = Mid$(TESTVALUE$, N%, 1) 'Get nth character of passed string + CHARVALUE% = Asc(TVC$) 'Get decimal ASCII code for nth character + If ((CHARVALUE% < 48) Or (CHARVALUE% > 57)) Then + ISPOSNUMBER% = 0 'Character not ASCII code for 0 through 9 + End If + N% = N% - 1 + Loop + +End Function +#End If + + + + + + + + + +Private Function funcIsRenameDSname(ByVal strWorkOrder) As Boolean + ' This function returns "True" if the "trimmed" values of the two strings that are passed + ' to it match. + ' + On Error GoTo ErrorHandler + + If (Trim(strFirst) = Trim(strSecond)) Then + funcIsInvalidDSname = True ' Strings match. + Else + funcIsInvalidDSname = False ' Strings do not match. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsMatchingString = False ' Error value. + MsgBox ("Error in ""funcIsInvalidDSname"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + + + + + + + + + + +Private Function funcIsInvalidDSname(ByVal strFileName) As Boolean + ' This function returns "True" if the "trimmed" values of the two strings that are passed + ' to it match. + ' + On Error GoTo ErrorHandler + + If (Trim(strFirst) = Trim(strSecond)) Then + funcIsInvalidDSname = True ' Strings match. + Else + funcIsInvalidDSname = False ' Strings do not match. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsMatchingString = False ' Error value. + MsgBox ("Error in ""funcIsInvalidDSname"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + + + + + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.vbp new file mode 100644 index 0000000..6e341df --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\..\..\Windows\SysWOW64\msstdfmt.dll#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; TABCTL32.OCX +Module=A_Main; DFWDS.bas +Form=frmDSfiles.frm +Startup="Sub Main" +HelpFile="" +Title="PrintDSCAmost" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.vbw new file mode 100644 index 0000000..6b81a4f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/frmDSfiles.frm b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/frmDSfiles.frm new file mode 100644 index 0000000..c50dbc2 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/frmDSfiles.frm @@ -0,0 +1,291 @@ +VERSION 5.00 +Begin VB.Form frmDSfiles + BorderStyle = 1 'Fixed Single + Caption = "Datasheet Files" + ClientHeight = 9555 + ClientLeft = 45 + ClientTop = 375 + ClientWidth = 8535 + Icon = "frmDSfiles.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form1" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 9555 + ScaleWidth = 8535 + StartUpPosition = 1 'CenterOwner + Begin VB.ListBox lstInvalidDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":030A + Left = 3600 + List = "frmDSfiles.frx":0311 + Sorted = -1 'True + TabIndex = 13 + Top = 1560 + Width = 2295 + End + Begin VB.ListBox lstRenameDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":0323 + Left = 6120 + List = "frmDSfiles.frx":032A + Sorted = -1 'True + TabIndex = 12 + Top = 1560 + Width = 2295 + End + Begin VB.TextBox txtRenameCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 7200 + TabIndex = 10 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.TextBox txtInvalidCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 4680 + TabIndex = 6 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.DriveListBox vlbDriveSelect + Height = 315 + Left = 120 + TabIndex = 5 + Top = 1320 + Width = 3255 + End + Begin VB.DirListBox dlbFolderSelect + Height = 3015 + Left = 120 + TabIndex = 4 + Top = 1680 + Width = 3255 + End + Begin VB.CommandButton btnProcess + Caption = "Process" + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 1 + ToolTipText = "Click to print text datasheets from data in stored-data file." + Top = 4920 + Width = 2055 + End + Begin VB.CommandButton btnExit + Cancel = -1 'True + Caption = "Exit Datasheet Program " + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 0 + ToolTipText = "Click to exit the program." + Top = 6240 + Width = 2055 + End + Begin VB.Label lblRenameCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 11 + Top = 9120 + Width = 975 + End + Begin VB.Label lblRenameDS + Alignment = 2 'Center + Caption = "Files to Rename" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 9 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidDS + Alignment = 2 'Center + Caption = "Invalid DS Names" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 8 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 7 + Top = 9120 + Width = 975 + End + Begin VB.Label lblMain + Alignment = 2 'Center + Caption = "Select Folder to List Datasheet Files with Invalid Names or That Need to be Renamed for the Website" + BeginProperty Font + Name = "Arial" + Size = 15.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 735 + Left = 120 + TabIndex = 3 + Top = 120 + Width = 8295 + End + Begin VB.Label lblFileSelect + Alignment = 2 'Center + Caption = "Select Datasheet Folder" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 120 + TabIndex = 2 + Top = 960 + Width = 3255 + End +End +Attribute VB_Name = "frmDSfiles" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + 'Put operations to run when the form loads here. + Me.lstInvalidDS.Clear + Me.lstRenameDS.Clear +End Sub + +Private Sub Form_Unload(Cancel As Integer) + 'The form is unloaded here, since the "Cancel" parameter is unmodified by the unload event. + End 'Exit program. +End Sub + +Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) + If (KeyCode = vbKeyF10) Then + Unload Me 'Call form unload event (and run unload code). + End If +End Sub + +Private Sub dlbFolderSelect_Change() + 'flbFileSelect.Path = dlbFolderSelect.Path + 'Call subProcessDatasheetFiles(dlbFolderSelect.Path) + Call subDirList(dlbFolderSelect.Path) + 'Me.txtInvalidCount.Text = Me.lstInvalidDS.ListCount + 'Me.txtInvalidCount.Text = Me.lstRenameDS.ListCount +End Sub + +Private Sub vlbDriveSelect_Change() + ' The Drive property also returns the volume label, so trim it. + dlbFolderSelect.Path = Left$(vlbDriveSelect.Drive, 1) & ":\" +End Sub + +Private Sub btnExit_Click() + Unload Me +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/frmDSfiles.frx b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/frmDSfiles.frx new file mode 100644 index 0000000..91de641 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-24/frmDSfiles.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.bas new file mode 100644 index 0000000..8e22665 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.bas @@ -0,0 +1,659 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2014_09_26" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/24 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = this file, main code module. +' VB FORMS: frmDBselect.frm = form to select directory and .DAT file for model database. +' frmDATAselect.frm = form to select .DAT file for stored model datasheet data and print +' text file datasheets. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/24 PWR Initial version. +' +' ------------------------------------------------------------------------------------------------------------------------------------- + +'---------------------------------------------------------------------------------------------------- +' Hard-coded values. +'---------------------------------------------------------------------------------------------------- +Public Const PRINTSHEET_SUBDIR = "PRINT" ' Hardcoded printed datasheet directory (below folder with .DAT files). +Public Const NUMPTS = 5 ' Hardcoded number of points for accuracy/linearity measurements. +Public Const NUMTESTS = 20 ' Hardcoded maximum array index (# of stored tests) for STATUS (strTestDATSTRING) and other arrays. + +' Global variables. +Public strDBFILEname As String ' Global variable to hold database (.DAT) file name. +Public strDBFILEfolder As String ' Global variable to hold database (.DAT) file folder. +Public strDATFILEname As String ' Global variable to hold stored datasheet data (.DAT) file name. +Public strDATFILEfolder As String ' Global variable to hold stored datasheet data (.DAT) file folder. +Public iFileCount As Integer ' Count of number of text datasheet files "printed". +Public iDupCount As Integer ' Count of number of text datasheet files "printed" over an existing file. +Public bDisplayMessages As Boolean ' Flag, "True" to display error messages in various functions and subroutines. +Public bPrintFailingUnits As Boolean ' Flag, "True" to also print text log files from failing units. + +' Global arrays. +Public strTestNAMES(1 To NUMTESTS) As String ' Global array for the Final Test test names. +Public strTestUNITS(1 To NUMTESTS) As String ' Global array for the Final Test test units. +Public strTSPEC(1 To NUMTESTS) As String ' Global array for the Final Test test limits strings for printed datasheet. +Public strMODNAME As String ' Global variable for module model name: "SCM5B30-1419", for example. +Public strSerialNumber As String ' Global variable for work order-serial number (collectively: Serial Number). +Public strDATETESTED As String ' Global variable for date tested. +' Global array for the Final Test test status read from the .DAT file (this includes the "PASS" or "FAIL" status, +' test results, and the number of decimal points to display). +Public strTestDATSTRING(1 To NUMTESTS) As String +' Global arrays for the Accuracy/Linearity test data read from the .DAT file. +Public strTSIM(1 To 5) As String ' Input value during acc/lin test (index is meas. #). +Public strOUTCALC(1 To 5) As String ' Calculated output value during acc/lin test (index is meas. #). +Public strOUTMEAS(1 To 5) As String ' Measured output value during acc/lin test (index is meas. #). +Public strERROROUT(1 To 5) As String ' Calculated output error during acc/lin test (index is meas. #). +Public strACCSTAT(1 To 5) As String ' PASS or FAILED status string during acc/lin test (index is meas. #). +' Global variable for data read from the datalog (.DAT) file. +Public sLOWV As Single ' Obsolete read value from datalog file. +Public sHIGHV As Single ' Obsolete read value from datalog file. +Public sTOTLRESPEC As Single ' Obsolete read value from datalog file. + + +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + + On Error GoTo ErrorHandler + + ' Initialize Final Test names and units for tests and stored + ' values for data read from datalog and database files. + + '------------------------------------------------------ + ' Display program screen. + ' NOTE: if screen is shown modal, it will NOT show up + ' in the taskbar nor be found by clicking alt-tab to + ' select open programs! + '------------------------------------------------------ + + 'frmDBselect.Show vbModal ' Show screen (modal). + frmDSfiles.Show ' Show screen (nonmodal). + + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + + MsgBox ("Error in ""Main"" subroutine = " & Err.Description) + +End Sub + +Public Function funcMakePathFromFolder(ByVal strSubfolderName As String) As Boolean + '------------------------------------------------------------------------------------- + ' Function to create directories (folders) as needed, based on the passed parameter. + ' + ' NOTE: The "strSubfolderName" parameter is assumed to be a complete path, including + ' drive letter. This subroutine does not handle other path forms, such as + ' those starting with a "\\" (as in "\\fileserver\") and will generate an + ' error message and return "False" if an invalid folder name is passed. + '------------------------------------------------------------------------------------- + Dim arTemp() As String ' Dynamic array to store parsed values from "Split" function. + Dim iArrayIndex As Long ' String-array index. + Dim strFolder As String ' (Re)combined folder name string, concatenated piece by piece from original. + Dim objFSO As New Scripting.FileSystemObject ' New instance of FileSystemObject. + + On Error GoTo ErrorHandler + + 'strFolder = sFolderRoot & "\" ' Initialize to root. + 'strFolder = Left$(strSubfolderName, 2) & "\" ' Initialize to drive letter and backslash. + strFolder = "" ' Initialize to drive letter and backslash. + + arTemp = Split(strSubfolderName, "\") ' Split "full" folder name to array of strings at each backslash. + + ' For each split string (folder name) check if folder already exists. Lower and upper bounds of array are determined + ' by the array itself (the number of strings depends on the contents of the "full" folder name (complete path). The + ' initial string should be the drive name. If the folder does not exist, it is created. The "combined" folder name is + ' then re-combined by adding a backslash and then the next string in the array (the next folder name). + For iArrayIndex = LBound(arTemp) To UBound(arTemp) + strFolder = strFolder & arTemp(iArrayIndex) & "\" + If Not objFSO.FolderExists(strFolder) Then + Call objFSO.CreateFolder(strFolder) + End If + Next iArrayIndex + Set objFSO = Nothing + + funcMakePathFromFolder = True ' Set function return before exit. + + Exit Function ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Set objFSO = Nothing + funcMakePathFromFolder = False ' Set function error return. + MsgBox ("Error in function ""funcMakePathFromFolder"" = " & Err.Description & vbCrLf & _ + "Folder name = " & strFolder & vbCrLf & _ + "Function returning ""False""!") +End Function + +Public Sub subDirListFSO(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim objFSO As FileSystemObject + Dim objFolder As Folder + Dim objFile As File + Dim NextRow As Long + Dim iCount As Integer + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject. + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get the folder. + Set objFolder = objFSO.GetFolder(strFolderName) + + 'If the folder does not contain files, exit the sub. + 'If (objFolder.Files.Count = 0) Then + ' MsgBox "No files were found...", vbExclamation + ' Exit Sub + 'End If + + iCount = 0 'Initialize. + + 'Loop through each file in the folder + For Each objFile In objFolder.Files + frmDSfiles.lstInvalidDS.AddItem objFile.Name + iCount = iCount + 1 + frmDSfiles.txtInvalidCount.Text = iCount + Next objFile + + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDirListFSO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Public Sub subDirList(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim strFileName As String + Dim strDirSpec As String + Dim lCountInvalid As Long + Dim lCountRename As Long + Dim lCountAll As Long + Dim strMoveLoc As String + Dim strLogFileNameLoc As String + Dim strDatasheetLoc As String + + On Error GoTo ErrorHandler + + + 'Initialize file names and locations. + 'This is TEMPORARY, since they should + 'eventually be read from a file. + strMoveLoc = "C:\_CODE\DFWDS\Bad_Datasheets" + strLogFileNameLoc = "C:\_CODE\DFWDS\Log\DFWDS.log" + strDatasheetLoc = "C:\_CODE\DFWDS\WebDatasheets" + + 'Initialize. + lCountInvalid = 0 + lCountRename = 0 + lCountAll = 0 + frmDSfiles.lstInvalidDS.Clear + frmDSfiles.lstRenameDS.Clear + + 'Set Dir$ function specification (directory path and search criteria). + 'strDirSpec = strFolderName & "\*.txt" + strDirSpec = strFolderName & "\*.*" + strFileName = Dir$(strDirSpec, vbNormal) + + 'Loop through each file in the folder + Do While (strFileName <> "") + strFileName = Dir$ + If (strFileName <> "") Then + Call subProcessDSfile(strFileName, strMoveLoc, strLogFileNameLoc, lCountRename, lCountInvalid) + lCountAll = lCountAll + 1 'Increment total count. + End If + Loop + + 'Set count displays. + frmDSfiles.txtInvalidCount.Text = lCountInvalid + frmDSfiles.txtRenameCount.Text = lCountRename + frmDSfiles.txtAllCount.Text = lCountAll + frmDSfiles.Refresh + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDirList"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subProcessDSfile(ByVal strDSfileName As String, ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, _ + ByRef lCountRename As Long, ByRef lCountInvalid As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the passed file name. If it is determined to be an invalid name for the Dataforth + 'website, the file is moved to the passed directory location and this action is recorded in a log file + 'whose name and location is also passed as a parameter. If the file name matches the format of "encoded" + 'datasheet file names from the DOS test programs, the file is renamed to the appropriate "unencoded" + 'datasheet file name and this action is also recorded to the specified log file. The subroutine posts + 'error messages for problems that may be encountered during file processing. + ' + ' Inputs: + ' strDSfileName: Datasheet file name. + ' strDSmoveLocation: Directory location that invalid files are copied. Invalid files include non-text + ' files and files with names that do not match the format for the Dataforth website. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' lCountInvalid: Passes count of invalid datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + ' lCountRename: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalid: Passes count of invalid datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + ' lCountRename: Passes count of renamed datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strWorkOrderNum As String 'Work order number. + Dim strFullFileName As String 'Full file name (including extension). + Dim strFileNameOnly As String 'File name (only). + Dim iDashLoc As Integer 'Dash location in file name (only) string. + Dim iFNOlength As Integer 'Length of file name (only) string. + Dim strWOdecoded As String 'Work order number. + + On Error GoTo ErrorHandler + + 'Get uppercase-only version of the full file name. + 'This is necessary for later processing of the + 'datasheet files (including determining whether + 'they are validly-named datasheet files). + strFullFileName = UCase$(strDSfileName) + + 'Get the file name (only). This should be the (encoded + 'or unencoded) module serial number. Note that the + 'function requires a full file name already in + 'all-UPPERCASE. + strFileNameOnly = funcGetFileNameOnly(strFullFileName) + + 'Check for text file. + If (strFileNameOnly = "") Then + 'Not a text file (null return from funcGetFileNameOnly). + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-text file. + End If + + 'Check for valid dash location (and/or existence) and a valid dash number. + iDashLoc = funcGetDashLoc(strFileNameOnly) 'Get dash location. + + 'Check for valid location. + If Not (funcGetDashLoc(strFileNameOnly) > 0) Then + 'Dash (or dash number) is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + + 'Parse work order# (characters to the left of + 'the dash) from the serial number string. + strWorkOrderNum = Left$(strFileNameOnly, iDashLoc - 1) + + If (funcIsAllNumbers(strWorkOrderNum) = True) Then + 'Work order number string is all numbers, + 'check for leading "0". + If (Left$(strWorkOrderNum, 1) = "0") Then + 'Leading "0" in all-numeric work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + Else + 'Work order string is not all numbers. Check if + 'it is matches the format of a DOS-encoded work + 'order number. + If (funcISrenameWO(strWorkOrderNum) = True) Then + 'DOS-encoded work order number. Rename file + 'to unencoded datasheet file name. + Call subDSrename(strFullFileName, strDSlogNameLoc, lCountRename) + Else + 'Not a DOS-encoded work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + End If + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcGetFileNameOnly(ByVal strFullFileName As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned + 'if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem (such as a blank file name passed to the function), a null string + 'is returned. + ' + 'NOTE: The passed full file name must be in all-UPPERCASE for the ".TXT" check to work. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strFullFileName) 'Get length of the full file name. + strSerial = Left$(strFullFileName, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcGetFileNameOnly = strSerial + Else + funcGetFileNameOnly = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcGetFileNameOnly = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcGetFileNameOnly = "" 'Error value. + MsgBox ("Error in ""funcGetFileNameOnly"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Function funcIsAllNumbers(ByVal strTestString As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'Function that checks whether the passed string consists of only numerical characters. The function + 'returns "True" if each character in the string is a number, and "False" if any character is not + 'a number or if there is some other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strChar As String + Dim iDx As Integer + + On Error GoTo ErrorHandler + + 'Initialize to "all numbers" value. + funcIsAllNumbers = True + + For iDx = 1 To Len(strTestString) 'Loop from 1st character to last character of string. + 'See if the next character is a non-number. + strChar = Mid$(strTestString, iDx, 1) 'Get next character. + If ((strChar < "0") Or (strChar > "9")) Then 'Character is not "0" through "9". + funcIsAllNumbers = False 'Set "not all numbers" value. + Exit For 'Exit the loop (no need to continue after first non-number). + End If + Next iDx + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsAllNumbers = False 'Error ("not all numbers") value. + MsgBox ("Error in ""funcIsAllNumbers"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetDashLoc(ByVal strFileNameOnly As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the dash ("-") location in the passed file name (only) string. It returns + 'an error value of "0" if no dash is found, or more than one dash is found, if there are more + 'than one characters after the dash, and if any of the characters after the dash are not a + 'number, or if there are any other problems in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + Dim strDashNum As String 'Dash number string. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strFileNameOnly) 'Length of file name (only) string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strFileNameOnly, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strFileNameOnly, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end (dash number + 'more than two characters, or less than one). + funcGetDashLoc = 0 'Error value (invalid dash). + Else + 'Dash number is one or two characters. Get for an all-number dash number. + strDashNum = Mid$(strFileNameOnly, iDashLocL + 1, iSTRlength - iDashLocL) + If (funcIsAllNumbers(strDashNum) = True) Then + 'Dash number is all numbers. + funcGetDashLoc = iDashLocL 'Good value (valid dash). + Else + 'Dash number is not valid (not all numbers). + funcGetDashLoc = 0 'Error value (invalid dash). + End If + End If + Else + 'More than one dash in the serial string. + funcGetDashLoc = 0 'Error value (invalid dash). + End If + + Exit Function 'Exit before error handler. +ErrorHandler: + funcGetDashLoc = 0 'Error (not valid) value. + MsgBox ("Error in ""funcIsValidDash"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDecodeWOchar(ByVal strWOnum As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns a two-character string decoded from the first character of the + 'passed work order number string. If the first character is "A" through "J", the + 'function returns "10" through "19", respectively, which represents the values that + 'are encoded in valid DOS-encoded datasheet file names. If the first character is + 'not "A" or "J" or a letter in between, or if there is some problem in the function, + 'the function returns a null string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strFirstChar As String 'First character in passed work order number string. + + On Error GoTo ErrorHandler + + If (strWOnum = "") Then + 'Null string, return error value (null string). + funcDecodeWOchar = "" 'Error value. + Else + 'String has at least one character, check for "A" through "J". + strFirstChar = Left$(strWOnum, 1) 'Get first character of passed work order number. + Select Case strFirstChar + Case strFirstChar = "A" + funcDecodeWOchar = "10" 'Decode of first character. + Case strFirstChar = "B" + funcDecodeWOchar = "11" 'Decode of first character. + Case strFirstChar = "C" + funcDecodeWOchar = "12" 'Decode of first character. + Case strFirstChar = "D" + funcDecodeWOchar = "13" 'Decode of first character. + Case strFirstChar = "E" + funcDecodeWOchar = "14" 'Decode of first character. + Case strFirstChar = "F" + funcDecodeWOchar = "15" 'Decode of first character. + Case strFirstChar = "G" + funcDecodeWOchar = "16" 'Decode of first character. + Case strFirstChar = "H" + funcDecodeWOchar = "17" 'Decode of first character. + Case strFirstChar = "I" + funcDecodeWOchar = "18" 'Decode of first character. + Case strFirstChar = "J" + funcDecodeWOchar = "19" 'Decode of first character. + Case Else + 'Not "A" through "J" + funcDecodeWOchar = "" 'Error value. + End Select + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcDecodeWOchar = "" 'Error value. + MsgBox ("Error in ""funcDecodeWOchar"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcISrenameWO(ByVal strWOnumber) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed work order number matches the format of a DOS-encoded + 'work order number (for work orders above the value of "99,999"). A DOS-encoded work order number + 'will be five characters long, start with "A" through "J", and have all numbers for the remaining + 'characters. The function will return "False" if any of these conditions are not true, or there is + 'any other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLastFour As String + Dim strFirstOne As String + + On Error GoTo ErrorHandler + + If (Len(strWOnumber) <> 5) Then + 'Not five characters long. + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strFirstOne = UCase$(Left$(strWOnumber, 1)) + If ((strFirstOne < "A") Or (strFirstOne > "J")) Then + 'First character not "A" through "J". + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strLastFour = Right$(strWOnumber, 4) + If (funcIsAllNumbers(strLastFour) = True) Then + funcISrenameWO = True 'Set "valid rename string" value. + Else + 'Last four characters not all numberss. + funcISrenameWO = False 'Set "not a valid rename string" value. + End If + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcISrenameWO = False 'Error value (not valid "rename" string). + MsgBox ("Error in ""funcISrenameWO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subDSmove(ByVal strFullFileName As String, ByVal strDSmoveLocation As String, _ + ByVal strDSlogNameLoc As String, ByRef lCountInvalid As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to move the file specified by the passed file name to the directory specified by the passed "move" + 'directory. This action is recorded in a log file whose name and location is also passed as a parameter. + 'The subroutine increments a by-reference count parameter for each file moved, which can be used for a + 'status display, such as "total invalid files", or some similar use. Errors encountered during the subroutine + 'will be logged in specified log file and error messages will be displayed. + ' + ' Inputs: + ' strFullFileName: Full file name of the file to be moved (includes file extension). + ' strDSmoveLocation: Directory location where the file is moved. + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' lCountInvalid: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalid: Passes count of invalid datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + + On Error GoTo ErrorHandler + + +'NOTE: The code below is temporary code for debug. The "move" code is not yet in the subroutine!!! + frmDSfiles.lstInvalidDS.AddItem strFullFileName 'Add file to be moved (invalid DS file name) to the list. + lCountInvalid = lCountInvalid + 1 'Increment count. + + + + Exit Sub ' Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDSmove"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subDSrename(ByVal strFullFileName As String, ByVal strDSlogNameLoc As String, ByRef lCountRename As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to rename the DOS-encoded datasheet file specified by the passed full file name and to recorded + 'this action in a log file whose name and location is also passed as a parameter. This subroutine is run + 'after a datasheet file with a DOS-encoded name is found (this is a valid datasheet file name with five + 'characters for the work order number, the first character "A" through "J", and all of the remaining work + 'order number characters are a number). The "A" through "J" first character is renamed to the appropriate + 'two-number "decoded" value ("10" through "19"), while the remaining characters in the file name portion of + 'the full datasheet file name remain unchanged. The subroutine increments a by-reference count parameter for + 'each file renamed, which can be used for a "total files renamed" status display, or some similar use. Errors + 'encountered during the subroutine will be logged in specified log file and error messages will be displayed. + ' + ' Inputs: + ' strFullFileName: Full file name of the file to be moved (includes file extension). + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' lCountRename: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountRename: Passes count of renamed datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + + On Error GoTo ErrorHandler + + +'NOTE: The code below is temporary code for debug. The "rename" code is not yet in the subroutine!!! + frmDSfiles.lstRenameDS.AddItem strFullFileName 'Add file to be renamed to the list. + lCountRename = lCountRename + 1 'Increment count. + + + Exit Sub ' Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDSrename"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.vbp new file mode 100644 index 0000000..086ed38 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\..\Windows\SysWOW64\msstdfmt.dll#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; TABCTL32.OCX +Module=A_Main; DFWDS.bas +Form=frmDSfiles.frm +Startup="Sub Main" +HelpFile="" +Title="PrintDSCAmost" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.vbw new file mode 100644 index 0000000..6b81a4f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/frmDSfiles.frm b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/frmDSfiles.frm new file mode 100644 index 0000000..5633535 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/frmDSfiles.frm @@ -0,0 +1,352 @@ +VERSION 5.00 +Begin VB.Form frmDSfiles + BorderStyle = 1 'Fixed Single + Caption = "Datasheet Files" + ClientHeight = 9555 + ClientLeft = 45 + ClientTop = 375 + ClientWidth = 8535 + Icon = "frmDSfiles.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form1" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 9555 + ScaleWidth = 8535 + StartUpPosition = 1 'CenterOwner + Begin VB.TextBox txtAllCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 1560 + TabIndex = 14 + Text = "0" + Top = 8040 + Width = 1215 + End + Begin VB.ListBox lstInvalidDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":030A + Left = 3600 + List = "frmDSfiles.frx":0311 + Sorted = -1 'True + TabIndex = 13 + Top = 1560 + Width = 2295 + End + Begin VB.ListBox lstRenameDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":0323 + Left = 6120 + List = "frmDSfiles.frx":032A + Sorted = -1 'True + TabIndex = 12 + Top = 1560 + Width = 2295 + End + Begin VB.TextBox txtRenameCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 7200 + TabIndex = 10 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.TextBox txtInvalidCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 4680 + TabIndex = 6 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.DriveListBox vlbDriveSelect + Height = 315 + Left = 120 + TabIndex = 5 + Top = 1320 + Width = 3255 + End + Begin VB.DirListBox dlbFolderSelect + Height = 3015 + Left = 120 + TabIndex = 4 + Top = 1680 + Width = 3255 + End + Begin VB.CommandButton btnProcess + Caption = "Process" + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 1 + ToolTipText = "Click to print text datasheets from data in stored-data file." + Top = 4920 + Width = 2055 + End + Begin VB.CommandButton btnExit + Cancel = -1 'True + Caption = "Exit Datasheet Program " + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 0 + ToolTipText = "Click to exit the program." + Top = 6240 + Width = 2055 + End + Begin VB.Label lblAllFiles + Alignment = 2 'Center + Caption = "All Files" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 720 + TabIndex = 16 + Top = 7680 + Width = 2295 + End + Begin VB.Label lblAllCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 480 + TabIndex = 15 + Top = 8160 + Width = 975 + End + Begin VB.Label lblRenameCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 11 + Top = 9120 + Width = 975 + End + Begin VB.Label lblRenameDS + Alignment = 2 'Center + Caption = "Files to Rename" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 9 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidDS + Alignment = 2 'Center + Caption = "Invalid DS Names" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 8 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 7 + Top = 9120 + Width = 975 + End + Begin VB.Label lblMain + Alignment = 2 'Center + Caption = "Select Folder to List Datasheet Files with Invalid Names or That Need to be Renamed for the Website" + BeginProperty Font + Name = "Arial" + Size = 15.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 735 + Left = 120 + TabIndex = 3 + Top = 120 + Width = 8295 + End + Begin VB.Label lblFileSelect + Alignment = 2 'Center + Caption = "Select Datasheet Folder" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 120 + TabIndex = 2 + Top = 960 + Width = 3255 + End +End +Attribute VB_Name = "frmDSfiles" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + 'Put operations to run when the form loads here. + Me.lstInvalidDS.Clear + Me.lstRenameDS.Clear + Me.txtAllCount.Text = "" + Me.txtInvalidCount.Text = "" + Me.txtRenameCount = "" +End Sub + +Private Sub Form_Unload(Cancel As Integer) + 'The form is unloaded here, since the "Cancel" parameter is unmodified by the unload event. + End 'Exit program. +End Sub + +Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) + If (KeyCode = vbKeyF10) Then + Unload Me 'Call form unload event (and run unload code). + End If +End Sub + +Private Sub dlbFolderSelect_Change() + 'flbFileSelect.Path = dlbFolderSelect.Path + 'Call subDirListFSO(dlbFolderSelect.Path) + 'Call subDirList(dlbFolderSelect.Path) + 'Me.txtInvalidCount.Text = Me.lstInvalidDS.ListCount + 'Me.txtInvalidCount.Text = Me.lstRenameDS.ListCount +End Sub + +Private Sub btnProcess_Click() + Call subDirList(dlbFolderSelect.Path) +End Sub + +Private Sub vlbDriveSelect_Change() + ' The Drive property also returns the volume label, so trim it. + dlbFolderSelect.Path = Left$(vlbDriveSelect.Drive, 1) & ":\" +End Sub + +Private Sub btnExit_Click() + Unload Me +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/frmDSfiles.frx b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/frmDSfiles.frx new file mode 100644 index 0000000..91de641 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-09-26/frmDSfiles.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.bas new file mode 100644 index 0000000..9495829 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.bas @@ -0,0 +1,1048 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2014_09_29" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/29 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = This file, the main code module. +' VB FORMS: frmSplash.frm = Program "splash" form displayed while the program is running. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/29 PWR Initial version. +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' +'Hard-coded "names" file name and location. +Public Const NAMES_FILE_NAME = "DFWDS_NAMES.txt" +Public Const NAMES_FILE_LOC = "C:\DFWDS" + +'Constants used as aliases for code readability. +Public Const DISPLAY_MESSAGES = "True" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const HIDE_MESSAGES = "False" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const MOVE_FILE = "True" 'Used, for example, by subDSmoveRename to control whether the file is moved or renamed. +Public Const RENAME_FILE = "False" 'Used, for example, by subDSmoveRename to control whether the file is moved or renamed. +' +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + ' + 'Define the local variables. + Dim strDSfolderName As String 'Datasheet file folder. + Dim strMoveLoc As String 'Invalid files are moved to this location. + Dim strLogFileName As String 'Log file name (only). + Dim strLogFileLoc As String 'Log file folder (only). + Dim strLogFileNameLoc As String 'Log file name and location. + Dim strLogFileLine As String 'Line for the log file. + Dim lCountRenameTotal As Long 'Number of datasheet files to be renamed. + Dim lCountInvalidTotal As Long 'Number of invalid datasheet files to be moved. + Dim lCountRenameGood As Long 'Number of datasheet files renamed. + Dim lCountInvalidGood As Long 'Number of invalid datasheet files. + Dim lCountAll As Long 'Total number of files in datasheet file directory. + Dim iLogFileHandle As Integer 'Log file number ("file handle"). + Dim dStartTime As Double 'Program start time. + Dim dEndTime As Double 'Program start time. + Dim strStartDate As String 'Date that the program is run. + Dim iOldMouse As Integer 'Store previous mouse state. + + On Error GoTo ErrorHandler + + 'Display program (splash) form. + frmSplash.Show + frmSplash.Refresh + + 'Get next valid file number (file + 'handle) for the log file. + iLogFileHandle = FreeFile + + 'Set start time. + dStartTime = Timer + + 'Initialize counts. + lCountRenameTotal = 0 + lCountInvalidTotal = 0 + lCountRenameGood = 0 + lCountInvalidGood = 0 + lCountAll = 0 + + 'Check for "names" file and read values from the file. End the + 'program if there is a problem with the "names" file. + If Not (functionNamesFileReadOK(strDSfolderName, strLogFileName, strLogFileLoc, strMoveLoc) = True) Then + End 'End the program. + End If + + 'Get starting date of program (for log file name and header) + 'and set full log file name based on the formatted date. + strStartDate = Format(Date$, "yyyy_mm_dd") 'Get starting date of program. + strLogFileName = strLogFileName & "_" & strStartDate & ".log" 'Get log file name with date. + + 'Open log file. + If (funcOpenLogFile(strLogFileName, strLogFileLoc, iLogFileHandle) = False) Then + Close #iLogFileHandle 'Close the log file. + Call subFileOpenMessage(strLogFileNameLoc) 'Display error message. + End 'Exit the program. + End If + + 'Write log file header. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Date: " & strStartDate & ", Time: " & Time$ + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + 'Call routine to process files in datasheet folder. + Call subProcessDSfolder(strDSfolderName, strMoveLoc, strLogFileNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood, lCountAll) + + 'Write log file footer information and close the log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total files processed = " & lCountAll + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Files to be renamed = " & lCountRenameTotal & vbCrLf & _ + "Files successfully renamed = " & lCountRenameGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Files to be moved = " & lCountInvalidTotal & vbCrLf & _ + "Files successfully moved = " & lCountInvalidGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total files to be changed = " & (lCountInvalidTotal + lCountRenameTotal) & vbCrLf & _ + "Total files successfully changed = " & (lCountInvalidGood + lCountRenameGood) + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + dEndTime = Timer 'Set end time. + strLogFileLine = "Elapsed time = " & Format(dEndTime - dStartTime, "##0.0") & " seconds" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + Close #iLogFileHandle + + 'Unload the program (splash) form. + Unload frmSplash 'Unload the network-copy program splash screen. + + End 'Exit program. + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Close #iLogFileHandle + MsgBox ("Error in ""Main"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End 'Exit program. +End Sub + +Public Function functionNamesFileReadOK(ByRef strDSfolderName As String, ByRef strLogFileName As String, _ + ByRef strLogFileLoc As String, ByRef strMoveLoc As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function checks for the presence of the "names" file holding the locations of the datasheet + 'file folder, the invalid file "move" folder, and the log file folder for the program as well as + 'the log file name. If the "names" file is found, this function reads lines from the file and puts + 'the values obtained in the appropriate variables that are returned, by reference, for use in other + 'routines. The validates the parameter names against the expected names for the appropriate lines + 'in the "names" folder, and for the folder values, validates the existence of the folders. The + 'function returns "True" if the "names" file is found and the parameter names and values read from + 'the names file can be validated against the expected values or the existence of the appropriate + 'folders. The function returns "False" if the "names" file cannot be found or read, if any of the + 'parameter names or values cannot be validated, or if there is any other problem in the function. + ' + 'NOTE: The log file name parameter value is validated outside of this function, when the log file + ' is first opened. + ' + ' Inputs: + ' All paramters are by-reference outputs whose values are read from the "names" file. + ' Outputs: + ' Error messages, log file entries. + ' Function return: The function returns "True" if the "names" file is found and can be + ' read and all of the parameters and values are appropriate. + ' strDSfolderName: Passes the name of the datasheet file folder by reference from + ' the validated value read from the "names" file. + ' strLogFileName: Passes the name of the log file by reference from the validated + ' value read from the "names" file. + ' strLogFileLoc: Passes the name of the log file folder by reference from the + ' validated value read from the "names" file. + ' strMoveLoc: Passes the name of the invalid file "move" folder by reference from + ' the validated value read from the "names" file. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strNamesFileLoc As String 'Location (folder) of the "names" file. + Dim strNamesFileNameLoc As String 'Name and location (folder) of the "names" file. + Dim strMessageString As String 'String for error message from reading "names" file lines. + Dim strParmName As String 'Parameter name read from the "names" file. + Dim strParmValue As String 'Parameter value read from the "names" file. + Dim strParmNameExpected As String 'Parameter value expected from the "names" file. + Dim iLineNumber As Integer 'Number of line read from the "names" file. + Dim iNamesFileHandle As Integer 'File number (file "handle") of the "names" file. + Dim objFSO As FileSystemObject 'File system object for "names" file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get next valid file number (file + 'handle) for the "names" file. + iNamesFileHandle = FreeFile + + 'Initialize. + strMessageString = "" 'Initialize as null (blank) string. + functionNamesFileReadOK = True 'Initialize as "all file entries read OK". + strDSfolderName = "" 'Set string to null. + strLogFileName = "" 'Set string to null. + strLogFileLoc = "" 'Set string to null. + strMoveLoc = "" 'Set string to null. + + 'Set file name and location from hardcoded constants. + strNamesFileLoc = NAMES_FILE_LOC 'Set "names" file folder to defined location. + If Right$(strNamesFileLoc, 1) <> "\" Then strNamesFileLoc = strNamesFileLoc & "\" 'Add trailing backslash (if needed). + strNamesFileNameLoc = strNamesFileLoc & NAMES_FILE_NAME 'Add "names" file name to folder. + + 'Check for existence of "names" file folder. + If Not funcFolderExists(strNamesFileLoc, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strNamesFileLoc & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Check for existence of the "names" file. + If Not (objFSO.FileExists(strNamesFileNameLoc)) Then + 'File not found. Post error return, display + 'error message, and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The ""names"" file: " & strNamesFileNameLoc & " was not found!" & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Destroy the file system object (it is + 'not used later in the function). + Set objFSO = Nothing + + 'Open the "names" file for input (reading line by line). + Open strNamesFileNameLoc For Input As iNamesFileHandle + + 'Read lines of the "names" file and check parameter names and values. + For iLineNumber = 1 To 4 + 'Set expected parameter names. + If (iLineNumber = 1) Then strParmNameExpected = "DATASHEET FOLDER NAME" + If (iLineNumber = 2) Then strParmNameExpected = "INVALID FILE MOVE FOLDER" + If (iLineNumber = 3) Then strParmNameExpected = "LOG FILE NAME" + If (iLineNumber = 4) Then strParmNameExpected = "LOG FILE FOLDER" + 'Get line of two comma-separated values and put into variables. + Input #iNamesFileHandle, strParmName, strParmValue + 'Trim the values read. + strParmName = Trim(strParmName) + strParmValue = Trim(strParmValue) + If (strParmName = strParmNameExpected) Then + 'Expected parameter name is found. + 'If the parameter is a location (folder) + 'paramter, check if the folder exists. + If (iLineNumber <> 3) Then + 'Folder parameter. Add a trailing backslash, if necessary. + If Right$(strParmValue, 1) <> "\" Then strParmValue = strParmValue & "\" + 'Check if folder exists. + If Not funcFolderExists(strParmValue, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strParmValue & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + End If + Else + 'The parameter name read from the "names" file does not match the + 'expected value. Post error return, display error message, + 'and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The parameter read from the ""names"" file" & vbCrLf & _ + "does not match the expected value!" & vbCrLf & _ + "Parameter read: " & strParmName & vbCrLf & _ + "Parameter expected: " & strParmNameExpected & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Set parameter values to appropriate variables. + If (iLineNumber = 1) Then strDSfolderName = strParmValue + If (iLineNumber = 2) Then strMoveLoc = strParmValue + If (iLineNumber = 3) Then strLogFileName = strParmValue + If (iLineNumber = 4) Then strLogFileLoc = strParmValue + Next iLineNumber + + 'Close the "names" file. + Close #iNamesFileHandle + + Exit Function 'Exit the function (before the error handler) if no error. +ErrorHandler: + Close #iNamesFileHandle 'Close the "names" file. + Set objFSO = Nothing 'Destroy the file system object. + functionNamesFileReadOK = False 'Error return value. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcOpenLogFile(ByVal strLogFileName As String, ByVal strLogFileLoc As String, _ + ByVal iLogFileHandle As Integer) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function opens the log file specified by the passed file name and folder for append using the + 'passed file "handle". The function returns "True" if there is no problem opening the file, and + 'returns "False" if any problem occurs. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFullFileName As String + + On Error GoTo ErrorHandler + + 'Make sure the folder name includes a trailing "\", then create + 'full file name (file name including folder) and open the file + 'for append. + If Right$(strLogFileLoc, 1) <> "\" Then strLogFileLoc = strLogFileLoc & "\" + strFullFileName = strLogFileLoc & strLogFileName 'Create full file name (name with location). + Open strFullFileName For Append As iLogFileHandle 'Open log file for append. + funcOpenLogFile = True 'Return value indicating no problems opening the file. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcOpenLogFile = False 'Error value. + MsgBox ("Error in ""funcOpenLogFile"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subFileOpenMessage(ByVal strLogFileNameLoc As String) + '---------------------------------------------------------------------------------------------------- + 'Subroutine to display error message about opening the log file using the passed full log file name + '(the file name complete with its directory location). + '---------------------------------------------------------------------------------------------------- + ' + MsgBox ("Error opening log file: " & strLogFileNameLoc & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcFolderExists(ByVal strFolderName As String, ByVal bDisplayErrMsg As Boolean) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed folder exists, and "False" if it does not, or there is + 'any other problem with the function. The passed flag displays a "file not found" message if "True", + 'or skips the message if "false" (for example, if a calling routine has its own error message). + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Make sure the folder name includes a trailing "\". + If Right$(strFolderName, 1) <> "\" Then strFolderName = strFolderName & "\" + + 'Check whether the folder exists. + If Not objFSO.FolderExists(strFolderName) Then + funcFolderExists = False 'Return value for "folder not found". + If (bDisplayErrMsg) Then + 'Display error message if the flag is "True". + MsgBox ("Folder not found: " & strFolderName & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End If + Else + funcFolderExists = True 'Return value for "folder found". + End If + + Set objFSO = Nothing 'Destroy file system object. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcFolderExists = False 'Error value. + Set objFSO = Nothing 'Destroy file system object. + MsgBox ("Error in ""funcFolderExists"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subProcessDSfolder(ByVal strFolderName As String, ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, _ + ByVal iLogFileHandle As Integer, ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long, _ + ByRef lCountAll As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the datasheet (and possibly other) files in the passed folder. The subroutine + 'initializes counts, writes a header to log file specified by the passed log file name and location, + 'and performs a directory listing of the passed folder, processing each file name through using + 'the "subProcessDSfile" subroutine to determine whether the file is an invalid datasheet file, in + 'which case the file is moved to the passed "move location" and this action is logged to the log file, + 'or is a valid DOS-encoded datasheet file name for datasheets with a work order number value greater + 'than "99,999", in which case the file is renamed to the "unecoded" datasheet file name and this + 'action is logged to the log file. Finally, the counts of the number of moved (invalid) files, renamed + 'files, and total of files in the directory are logged to the log file. + ' + ' Inputs: + ' strFolderName: Datasheet folder location. + ' strDSmoveLocation: Directory location that invalid files are moved. Invalid files include non-text + ' files and files with names that do not match the format for the Dataforth website. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountAll: Passes initial count of all files found in the datasheet folder to + ' the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountAll: Passes the count of all files found in the datasheet file folder + ' back to the calling routine by reference for status displays, etc. + ' Also used, on first call, to pass the initial count from the calling + ' routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFileName As String + Dim strFullFileName As String + Dim strDirSpec As String + + On Error GoTo ErrorHandler + + 'Initialize. + lCountInvalidTotal = 0 + lCountRenameTotal = 0 + lCountInvalidGood = 0 + lCountRenameGood = 0 + lCountAll = 0 + + 'Set Dir$ function specification (directory path and search criteria). + 'strDirSpec = strFolderName & "\*.txt" + strDirSpec = strFolderName & "\*.*" + strFileName = Dir$(strDirSpec, vbNormal) + + 'Loop through each file in the folder + Do While (strFileName <> "") + strFileName = Dir$ + If (strFileName <> "") Then + Call subProcessDSfile(strFileName, strFolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + lCountAll = lCountAll + 1 'Increment total count. + frmSplash.lblFileCount.Caption = lCountAll + frmSplash.lblCurrentFile.Caption = strFileName + frmSplash.lblFileCount.Refresh + frmSplash.lblCurrentFile.Refresh + End If + Loop + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfolder"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subProcessDSfile(ByVal strDSfileName As String, ByVal strDSfolderName As String, ByVal strDSmoveLocation As String, _ + ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer, _ + ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the passed file name. If it is determined to be an invalid name for the Dataforth + 'website, the file is moved to the passed directory location and this action is recorded in a log file + 'whose name and location is also passed as a parameter. If the file name matches the format of "encoded" + 'datasheet file names from the DOS test programs, the file is renamed to the appropriate "unencoded" + 'datasheet file name and this action is also recorded to the specified log file. The subroutine posts + 'error messages for problems that may be encountered during file processing, and passes file counts + '(total files found to be renamed or moved, files successfully rename or moved) to the calling routine. + ' + ' Inputs: + ' strDSfileName: Datasheet file name. + ' strDSmoveLocation: Directory location that invalid files are moved. Invalid files include non-text + ' files and files with names that do not match the format for the Dataforth website. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strWorkOrderNum As String 'Work order number. + Dim strFullFileName As String 'Full file name (including extension). + Dim strFileNameOnly As String 'File name (only). + Dim iDashLoc As Integer 'Dash location in file name (only) string. + Dim iFNOlength As Integer 'Length of file name (only) string. + Dim strWOdecoded As String 'Work order number. + + On Error GoTo ErrorHandler + + 'Get uppercase-only version of the full file name. + 'This is necessary for later processing of the + 'datasheet files (including determining whether + 'they are validly-named datasheet files). + strFullFileName = UCase$(strDSfileName) + + 'Get the file name (only). This should be the (encoded + 'or unencoded) module serial number. Note that the + 'function requires a full file name already in + 'all-UPPERCASE. + strFileNameOnly = funcGetFileNameOnly(strFullFileName) + + 'Check for text file. + If (strFileNameOnly = "") Then + 'Not a text file (null return from funcGetFileNameOnly). + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-text file. + End If + + 'Check for valid dash location (and/or existence) and a valid dash number. + iDashLoc = funcGetDashLoc(strFileNameOnly) 'Get dash location. + + 'Check for valid location. + If Not (funcGetDashLoc(strFileNameOnly) > 0) Then + 'Dash (or dash number) is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + + 'Parse work order# (characters to the left of + 'the dash) from the serial number string. + strWorkOrderNum = Left$(strFileNameOnly, iDashLoc - 1) + + If (funcIsAllNumbers(strWorkOrderNum) = True) Then + 'Work order number string is all numbers, + 'check for leading "0". + If (Left$(strWorkOrderNum, 1) = "0") Then + 'Leading "0" in all-numeric work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + Else + 'Work order string is not all numbers. Check if + 'it is matches the format of a DOS-encoded work + 'order number. + If (funcISrenameWO(strWorkOrderNum) = True) Then + 'DOS-encoded work order number. Rename file + 'to unencoded datasheet file name. + Call subDSmoveRename(RENAME_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Else + 'Not a DOS-encoded work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + End If + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcGetFileNameOnly(ByVal strFullFileName As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned + 'if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem (such as a blank file name passed to the function), a null string + 'is returned. + ' + 'NOTE: The passed full file name must be in all-UPPERCASE for the ".TXT" check to work. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strFullFileName) 'Get length of the full file name. + strSerial = Left$(strFullFileName, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcGetFileNameOnly = strSerial + Else + funcGetFileNameOnly = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcGetFileNameOnly = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcGetFileNameOnly = "" 'Error value. + MsgBox ("Error in ""funcGetFileNameOnly"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Function funcIsAllNumbers(ByVal strTestString As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'Function that checks whether the passed string consists of only numerical characters. The function + 'returns "True" if each character in the string is a number, and "False" if any character is not + 'a number or if there is some other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strChar As String + Dim iDx As Integer + + On Error GoTo ErrorHandler + + 'Initialize to "all numbers" value. + funcIsAllNumbers = True + + For iDx = 1 To Len(strTestString) 'Loop from 1st character to last character of string. + 'See if the next character is a non-number. + strChar = Mid$(strTestString, iDx, 1) 'Get next character. + If ((strChar < "0") Or (strChar > "9")) Then 'Character is not "0" through "9". + funcIsAllNumbers = False 'Set "not all numbers" value. + Exit For 'Exit the loop (no need to continue after first non-number). + End If + Next iDx + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsAllNumbers = False 'Error ("not all numbers") value. + MsgBox ("Error in ""funcIsAllNumbers"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetDashLoc(ByVal strFileNameOnly As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the dash ("-") location in the passed file name (only) string. It returns + 'an error value of "0" if no dash is found, or more than one dash is found, if there are more + 'than one characters after the dash, and if any of the characters after the dash are not a + 'number, or if there are any other problems in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + Dim strDashNum As String 'Dash number string. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strFileNameOnly) 'Length of file name (only) string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strFileNameOnly, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strFileNameOnly, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end (dash number + 'more than two characters, or less than one). + funcGetDashLoc = 0 'Error value (invalid dash). + Else + 'Dash number is one or two characters. Get for an all-number dash number. + strDashNum = Mid$(strFileNameOnly, iDashLocL + 1, iSTRlength - iDashLocL) + If (funcIsAllNumbers(strDashNum) = True) Then + 'Dash number is all numbers. + funcGetDashLoc = iDashLocL 'Good value (valid dash). + Else + 'Dash number is not valid (not all numbers). + funcGetDashLoc = 0 'Error value (invalid dash). + End If + End If + Else + 'More than one dash in the serial string. + funcGetDashLoc = 0 'Error value (invalid dash). + End If + + Exit Function 'Exit before error handler. +ErrorHandler: + funcGetDashLoc = 0 'Error (not valid) value. + MsgBox ("Error in ""funcIsValidDash"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDecodeWOchar(ByVal strWOnum As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns a two-character string decoded from the first character of the + 'passed work order number string. If the first character is "A" through "J", the + 'function returns "10" through "19", respectively, which represents the values that + 'are encoded in valid DOS-encoded datasheet file names. If the first character is + 'not "A" or "J" or a letter in between, or if there is some problem in the function, + 'the function returns a null string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strFirstChar As String 'First character in passed work order number string. + + On Error GoTo ErrorHandler + + If (strWOnum = "") Then + 'Null string, return error value (null string). + funcDecodeWOchar = "" 'Error value. + Else + 'String has at least one character, check for "A" through "J". + strFirstChar = Left$(strWOnum, 1) 'Get first character of passed work order number. + If (strFirstChar = "A") Then + funcDecodeWOchar = "10" 'Decode of first character. + ElseIf (strFirstChar = "B") Then + funcDecodeWOchar = "11" 'Decode of first character. + ElseIf (strFirstChar = "C") Then + funcDecodeWOchar = "12" 'Decode of first character. + ElseIf (strFirstChar = "D") Then + funcDecodeWOchar = "13" 'Decode of first character. + ElseIf (strFirstChar = "E") Then + funcDecodeWOchar = "14" 'Decode of first character. + ElseIf (strFirstChar = "F") Then + funcDecodeWOchar = "15" 'Decode of first character. + ElseIf (strFirstChar = "G") Then + funcDecodeWOchar = "16" 'Decode of first character. + ElseIf (strFirstChar = "H") Then + funcDecodeWOchar = "17" 'Decode of first character. + ElseIf (strFirstChar = "I") Then + funcDecodeWOchar = "18" 'Decode of first character. + ElseIf (strFirstChar = "J") Then + funcDecodeWOchar = "19" 'Decode of first character. + Else + 'Not "A" through "J" + funcDecodeWOchar = "" 'Error value. + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcDecodeWOchar = "" 'Error value. + MsgBox ("Error in ""funcDecodeWOchar"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcISrenameWO(ByVal strWOnumber As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed work order number matches the format of a DOS-encoded + 'work order number (for work orders above the value of "99,999"). A DOS-encoded work order number + 'will be five characters long, start with "A" through "J", and have all numbers for the remaining + 'characters. The function will return "False" if any of these conditions are not true, or there is + 'any other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLastFour As String + Dim strFirstOne As String + + On Error GoTo ErrorHandler + + If (Len(strWOnumber) <> 5) Then + 'Not five characters long. + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strFirstOne = UCase$(Left$(strWOnumber, 1)) + If ((strFirstOne < "A") Or (strFirstOne > "J")) Then + 'First character not "A" through "J". + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strLastFour = Right$(strWOnumber, 4) + If (funcIsAllNumbers(strLastFour) = True) Then + funcISrenameWO = True 'Set "valid rename string" value. + Else + 'Last four characters not all numberss. + funcISrenameWO = False 'Set "not a valid rename string" value. + End If + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcISrenameWO = False 'Error value (not valid "rename" string). + MsgBox ("Error in ""funcISrenameWO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subDSmoveRename(ByVal bMoveFile As Boolean, ByVal strFullFileName As String, ByVal strDSfolderName As String, _ + ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer, _ + ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to move or rename the file specified by the passed file name and datasheet file folder. If the + 'move/rename parameter ("bMoveFile") is "True", the file is moved to the directory specified by the + 'passed "move" folder name. If the parameter is "False", the file is renamed from the DOS-encoded name to + 'the unencoded datasheet file name. In both cases, the "move" or "rename" is accomplished by copying the + 'file to the new name or location, and then deleting the old file if nothing has gone wrong. All actions, + 'including successful moves or renames, unsuccessful file copies, or unsuccessful file deletions, are + 'recorded in a log file whose name and location, as well as its file number (file "handle"), are passed + 'as parameters. The subroutine increments by-reference count parameters for each invalid or DOS-encoded + 'datasheet file found and for each successful file move or rename. These can be used for a status displays, + 'such as "total invalid files" or "total renamed files", or similar, and can include lines in the log file + 'footer after the program has completed processing the files in the datasheet file folder. Errors encountered + 'during the subroutine will be logged in the specified log file rather than displayed to the screen, since + 'screen display would cause problems due to the number of files typically processed in the datasheet file + 'folder. + ' + 'NOTE: Since the existence of all of the relevant directories is verified by one of the calling routines + ' directory checking is not repeated here to save program time (since this function is called for + ' every relevant file). + ' + ' Inputs: + ' bMoveFile: This parameter is "True" to move the specified file to the "move" + ' folder (usually used for invalid files in the datasheet file + ' folder), or "False" to rename the specified file from the + ' DOS-encoded work order number (for values above "99,999") to the + ' unencoded work order number (file name matching the module serial + ' number contained within the datasheet file). + ' strFullFileName: Full file name of the file to be moved (includes file extension). + ' strDSfolderName: Datasheet folder location. + ' strDSmoveLocation: Directory location where the file is moved. + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLogFileLine As String 'String for a line of information for the log file. + Dim strFullFileRename As String 'Full file name (name and extension) for the renamed (unencoded) datasheet file name. + Dim strFullFileNameLoc As String 'Full file name (name and extension) and folder of the file in the datasheet folder. + Dim strFullFileRenameLoc As String 'Full file name (name and extension) and folder for the renamed (unencoded) datasheet file name. + Dim strRenameFirstChars As String 'First character of file to be renamed, or (decoded) first two characters of renamed file. + Dim iLenFullFileName As Integer 'Length of the full file name of the file to be renamed. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + 'Initialize strings to null. + strLogFileLine = "" + strFullFileRename = "" + strFullFileNameLoc = "" + strFullFileRenameLoc = "" + strRenameFirstChars = "" + + 'Increment the count of the total (found) files of the appropriate type. + If (bMoveFile) Then + 'Increment count of invalid datasheet files (files to move) found in datasheet folder. + lCountInvalidTotal = lCountInvalidTotal + 1 + Else + 'Increment count of DOS-encoded datasheet files (files to rename) found in datasheet folder. + lCountRenameTotal = lCountRenameTotal + 1 + End If + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Create the full file name and location from the full file + 'name and the folder location. First, add a trailing + 'backslash, if needed, to the folder location. + If Right$(strDSfolderName, 1) <> "\" Then strDSfolderName = strDSfolderName & "\" + strFullFileNameLoc = strDSfolderName & strFullFileName + + 'If the file needs to be renamed, create the full "rename" file name + '(file name and extension) from the original DOS-encoded name, then + 'create the full name/location (file name and folder location). + If Not (bMoveFile) Then + 'File to be renamed. Decode first character of full file name. + strRenameFirstChars = Left$(strFullFileName, 1) 'Get first character of file to be renamed. + iLenFullFileName = Len(strFullFileName) 'Get the length of the full file name of the file to be renamed. + 'Use the "decode work order character" function to decode the first character of the full + 'file name of the file to be renamed (note, the function name implies the passed string + 'is the work order number only, but since the function only uses the first character of + 'the string, it also works for the full file name). + strRenameFirstChars = funcDecodeWOchar(strFullFileName) 'Get decoded first two characters of full file name. + 'Create the renamed file name, by combining the new decoded characters with the characters of the full + 'datasheet file name to be renamed, but skipping the first character. + strFullFileRename = Right$(strFullFileName, iLenFullFileName - 1) 'Get full file name minus the first character. + strFullFileRename = strRenameFirstChars & strFullFileRename 'Create full rename file name by adding decoded characters. + strFullFileRenameLoc = strDSfolderName & strFullFileRename 'Create full rename file name/location by adding folder. + End If + + 'Create "could not copy" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the CopyFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "copy good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not copy" message. + strLogFileLine = "Could not copy file: " & strFullFileNameLoc & " to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not copy file: " & strFullFileNameLoc & " to: " & strFullFileRename + End If + + 'Copy the invalid file or file to be renamed in the datasheet folder. + 'For moves, copy to the "move" directory. For rename, copy to a new + 'name in the same folder. File copy parameters: + 'source (full file name/loc), destination (folder + 'only or full (rename) file name/loc), "True" for + 'overwrite if a file of same name already exists + 'in the destination. + If (bMoveFile) Then + 'Move invalid file. Start by copying to new folder location. + Call objFSO.CopyFile(strFullFileNameLoc, strDSmoveLocation, True) + Else + 'Rename DOS-encoded datasheet file. Start by copying to name in same folder. + Call objFSO.CopyFile(strFullFileNameLoc, strFullFileRenameLoc, True) + End If + + 'Create "could not delete" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the DeleteFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "delete good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not delete" message. + strLogFileLine = "Could not delete file: " & strFullFileNameLoc & " after copy to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not delete file: " & strFullFileNameLoc & " after copy to: " & strFullFileRename + End If + + + + 'Delete the invalid file in the datasheet folder. + 'File delete parameters: full file/loc, "True" + 'for "force" (ignore read-only). + Call objFSO.DeleteFile(strFullFileNameLoc, True) + + 'Since there were no problems to this point (no jump to the error handler), + 'create "successfully moved" or "successfully renamed" message, increment + 'the appropriate count, and write the message to the log file. + If (bMoveFile) Then + strLogFileLine = "Moved file: " & strFullFileNameLoc & " to: " & strDSmoveLocation + lCountInvalidGood = lCountInvalidGood + 1 'Increment count of successfully moved files. + Else + strLogFileLine = "Renamed file: " & strFullFileNameLoc & " to: " & strFullFileRename + lCountRenameGood = lCountRenameGood + 1 'Increment count of successfully renamed files. + End If + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + Set objFSO = Nothing 'Destroy file system object. + + Exit Sub ' Exit before error handler. +ErrorHandler: + Print #iLogFileHandle, strLogFileLine 'Write previously-generated error message to log file. + Set objFSO = Nothing 'Destroy file system object. + 'NOTE: Since this function processes many files, errors should be posted (only) to the log + ' file, NOT to the screen. Therefore, the following two lines (single line of code) + ' are (is) commented out. + 'MsgBox ("Error in ""subDSmoveRename"" = " & Err.Description & vbCrLf & vbCrLf & _ + ' "Contact engineering before proceeding!"), vbCritical +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.vbp new file mode 100644 index 0000000..540b885 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\Windows\SysWOW64\MSSTDFMT.DLL#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao350.dll#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; tabctl32.ocx +Module=A_Main; DFWDS.bas +Form=frmSplash.frm +Startup="Sub Main" +HelpFile="" +Title="DFWDS" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.vbw new file mode 100644 index 0000000..f62f99f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/frmSplash.frm b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/frmSplash.frm new file mode 100644 index 0000000..ea07586 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/frmSplash.frm @@ -0,0 +1,204 @@ +VERSION 5.00 +Begin VB.Form frmSplash + AutoRedraw = -1 'True + BorderStyle = 3 'Fixed Dialog + ClientHeight = 4344 + ClientLeft = 252 + ClientTop = 1416 + ClientWidth = 7428 + ClipControls = 0 'False + ControlBox = 0 'False + Icon = "frmSplash.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form2" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 4344 + ScaleWidth = 7428 + StartUpPosition = 2 'CenterScreen + Begin VB.Frame frmMainFrame + Height = 4332 + Left = 0 + TabIndex = 0 + Top = 0 + Width = 7425 + Begin VB.Label lblCurrentFile + Caption = "Insert current file here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 9 + Top = 3840 + Width = 2412 + End + Begin VB.Label lblFileCount + Caption = "Insert file count here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 8 + Top = 3480 + Width = 2412 + End + Begin VB.Label lblProgName + Caption = "Program Name:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 7 + Top = 1320 + Width = 2655 + End + Begin VB.Label lblName + Caption = "Insert pgm name here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 6 + Top = 1680 + Width = 3615 + End + Begin VB.Label lblVersion + Caption = "Insert version here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 5 + Top = 2400 + Width = 3615 + End + Begin VB.Image imgLogo + Height = 3105 + Left = 0 + Picture = "frmSplash.frx":030A + Stretch = -1 'True + Top = 240 + Width = 3015 + End + Begin VB.Label lblCopyright + Caption = "Copyright 2014" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 2 + Top = 3120 + Width = 2415 + End + Begin VB.Label lblCompany + Caption = "Dataforth Corporation" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 1 + Top = 2880 + Width = 2415 + End + Begin VB.Label lblVersionCaption + Caption = "Program Version:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 3 + Top = 2040 + Width = 2655 + End + Begin VB.Label C + Caption = "Processing Dataforth Datasheet Files" + BeginProperty Font + Name = "Arial" + Size = 18 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 915 + Index = 0 + Left = 3480 + TabIndex = 4 + Top = 360 + Width = 3720 + End + End +End +Attribute VB_Name = "frmSplash" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + Me.lblName.Caption = PROGRAM_NAME + Me.lblVersion.Caption = PROGRAM_VERSION + Me.lblFileCount.Caption = "" + Me.lblCurrentFile.Caption = "" +End Sub + + + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/frmSplash.frx b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/frmSplash.frx new file mode 100644 index 0000000..57b2e47 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-01/frmSplash.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES(code test).txt b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES(code test).txt new file mode 100644 index 0000000..22aaed9 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES(code test).txt @@ -0,0 +1,78 @@ +DATASHEET FOLDER NAME, C:\DFWDS_TestFiles\Processed\Test_Datasheets +INVALID FILE MOVE FOLDER, C:\DFWDS_TestFiles\Processed\Bad_Datasheets +LOG FILE NAME, DFWDS +LOG FILE FOLDER, C:\DFWDS_TestFiles\Processed\Datasheets_Log +WEB FOLDER, C:\DFWDS_TestFiles\Processed\For_Web +OPERATION, WEBMOVE + +Last updated: 2014-10-02 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +OPERATION: This parameter controls the operation of the program, and +can be one of only four values: COUNT, LIST, INPLACE or WEBMOVE. + +The following are the names (parameter values) and descriptions +of the allowed OPERATIONs: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES(datasheets for web local).txt b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES(datasheets for web local).txt new file mode 100644 index 0000000..8442ca6 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES(datasheets for web local).txt @@ -0,0 +1,78 @@ +DATASHEET FOLDER NAME,C:\Datasheets_For_Web\Test_Datasheets +INVALID FILE MOVE FOLDER,C:\Datasheets_For_Web\Bad_Datasheets +LOG FILE NAME,DFWDS +LOG FILE FOLDER,C:\Datasheets_For_Web\Datasheets_Log +WEB FOLDER,C:\Datasheets_For_Web\For_Web +OPERATION,WEBMOVE + +Last updated: 2014-10-02 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +OPERATION: This parameter controls the operation of the program, and +can be one of only four values: COUNT, LIST, INPLACE or WEBMOVE. + +The following are the names (parameter values) and descriptions +of the allowed OPERATIONs: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES.txt b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES.txt new file mode 100644 index 0000000..8442ca6 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/History/DFWDS_2014-10-02/DFWDS_NAMES.txt @@ -0,0 +1,78 @@ +DATASHEET FOLDER NAME,C:\Datasheets_For_Web\Test_Datasheets +INVALID FILE MOVE FOLDER,C:\Datasheets_For_Web\Bad_Datasheets +LOG FILE NAME,DFWDS +LOG FILE FOLDER,C:\Datasheets_For_Web\Datasheets_Log +WEB FOLDER,C:\Datasheets_For_Web\For_Web +OPERATION,WEBMOVE + +Last updated: 2014-10-02 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +OPERATION: This parameter controls the operation of the program, and +can be one of only four values: COUNT, LIST, INPLACE or WEBMOVE. + +The following are the names (parameter values) and descriptions +of the allowed OPERATIONs: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/Release/frmSplash.frm b/projects/dataforth-dos/dfwds-research/source/Release/frmSplash.frm new file mode 100644 index 0000000..ea07586 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/Release/frmSplash.frm @@ -0,0 +1,204 @@ +VERSION 5.00 +Begin VB.Form frmSplash + AutoRedraw = -1 'True + BorderStyle = 3 'Fixed Dialog + ClientHeight = 4344 + ClientLeft = 252 + ClientTop = 1416 + ClientWidth = 7428 + ClipControls = 0 'False + ControlBox = 0 'False + Icon = "frmSplash.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form2" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 4344 + ScaleWidth = 7428 + StartUpPosition = 2 'CenterScreen + Begin VB.Frame frmMainFrame + Height = 4332 + Left = 0 + TabIndex = 0 + Top = 0 + Width = 7425 + Begin VB.Label lblCurrentFile + Caption = "Insert current file here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 9 + Top = 3840 + Width = 2412 + End + Begin VB.Label lblFileCount + Caption = "Insert file count here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 8 + Top = 3480 + Width = 2412 + End + Begin VB.Label lblProgName + Caption = "Program Name:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 7 + Top = 1320 + Width = 2655 + End + Begin VB.Label lblName + Caption = "Insert pgm name here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 6 + Top = 1680 + Width = 3615 + End + Begin VB.Label lblVersion + Caption = "Insert version here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 5 + Top = 2400 + Width = 3615 + End + Begin VB.Image imgLogo + Height = 3105 + Left = 0 + Picture = "frmSplash.frx":030A + Stretch = -1 'True + Top = 240 + Width = 3015 + End + Begin VB.Label lblCopyright + Caption = "Copyright 2014" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 2 + Top = 3120 + Width = 2415 + End + Begin VB.Label lblCompany + Caption = "Dataforth Corporation" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 1 + Top = 2880 + Width = 2415 + End + Begin VB.Label lblVersionCaption + Caption = "Program Version:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 3 + Top = 2040 + Width = 2655 + End + Begin VB.Label C + Caption = "Processing Dataforth Datasheet Files" + BeginProperty Font + Name = "Arial" + Size = 18 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 915 + Index = 0 + Left = 3480 + TabIndex = 4 + Top = 360 + Width = 3720 + End + End +End +Attribute VB_Name = "frmSplash" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + Me.lblName.Caption = PROGRAM_NAME + Me.lblVersion.Caption = PROGRAM_VERSION + Me.lblFileCount.Caption = "" + Me.lblCurrentFile.Caption = "" +End Sub + + + diff --git a/projects/dataforth-dos/dfwds-research/source/Release/frmSplash.frx b/projects/dataforth-dos/dfwds-research/source/Release/frmSplash.frx new file mode 100644 index 0000000..57b2e47 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/Release/frmSplash.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Notes/Code to get files in folder.txt b/projects/dataforth-dos/dfwds-research/source/_Notes/Code to get files in folder.txt new file mode 100644 index 0000000..a55b2f0 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Notes/Code to get files in folder.txt @@ -0,0 +1,41 @@ +Public Function AllFiles(ByVal DirPath As String) As String() + Dim sFile As String + Dim lElement As Long + Dim sAns() As String + ReDim sAns(0) As String + + sFile = Dir(DirPath, vbNormal + vbHidden + vbReadOnly + vbSystem + vbArchive) + + If sFile <> "" Then + sAns(0) = sFile + Do + sFile = Dir + If sFile = "" Then Exit Do + lElement = IIf(sAns(0) = "", 0, UBound(sAns) + 1) + ReDim Preserve sAns(lElement) As String + sAns(lElement) = sFile + + Loop + End If + AllFiles = sAns +End Function + + + + + + + + + + + + + +Dim Files() as String = System.IO.Directory.GetFiles(folderpath) + + + + + + diff --git a/projects/dataforth-dos/dfwds-research/source/_Notes/DFWDS_NAMES(local test).txt b/projects/dataforth-dos/dfwds-research/source/_Notes/DFWDS_NAMES(local test).txt new file mode 100644 index 0000000..a05ec18 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Notes/DFWDS_NAMES(local test).txt @@ -0,0 +1,80 @@ +DATASHEET FOLDER NAME,C:\Datasheets_For_Web\Test_Datasheets +INVALID FILE MOVE FOLDER,C:\Datasheets_For_Web\Bad_Datasheets +LOG FILE NAME,DFWDS +LOG FILE FOLDER,C:\Datasheets_For_Web\Datasheets_Log +WEB FOLDER,C:\Datasheets_For_Web\For_Web +OPERATION,WEBMOVE + +Last updated: 2015-06-08 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +----------- +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +------------ +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +----------- +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +------------ +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +----------- +OPERATION: This parameter controls the operation of the program, and +can only be one of the values described below: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/_Notes/Decodes of A through J.txt b/projects/dataforth-dos/dfwds-research/source/_Notes/Decodes of A through J.txt new file mode 100644 index 0000000..8afab8e --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Notes/Decodes of A through J.txt @@ -0,0 +1,11 @@ + +Renamed file: C:\DFWDS\WebDatasheets\A2345-01.TXT to: 102345-01.TXT +Renamed file: C:\DFWDS\WebDatasheets\B2345-02.TXT to: 112345-02.TXT +Renamed file: C:\DFWDS\WebDatasheets\C2345-03.TXT to: 122345-03.TXT +Renamed file: C:\DFWDS\WebDatasheets\D2345-04.TXT to: 132345-04.TXT +Renamed file: C:\DFWDS\WebDatasheets\E2345-05.TXT to: 142345-05.TXT +Renamed file: C:\DFWDS\WebDatasheets\F2345-06.TXT to: 152345-06.TXT +Renamed file: C:\DFWDS\WebDatasheets\G2345-07.TXT to: 162345-07.TXT +Renamed file: C:\DFWDS\WebDatasheets\H2345-08.TXT to: 172345-08.TXT +Renamed file: C:\DFWDS\WebDatasheets\I2345-09.TXT to: 182345-09.TXT +Renamed file: C:\DFWDS\WebDatasheets\J2345-10.TXT to: 192345-10.TXT diff --git a/projects/dataforth-dos/dfwds-research/source/_Notes/HOW TO Recursively Search Directories by Using FileSystemObject.pdf b/projects/dataforth-dos/dfwds-research/source/_Notes/HOW TO Recursively Search Directories by Using FileSystemObject.pdf new file mode 100644 index 0000000..1609107 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Notes/HOW TO Recursively Search Directories by Using FileSystemObject.pdf differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.bas new file mode 100644 index 0000000..7decc19 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.bas @@ -0,0 +1,1181 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2015_06_08" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/29 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = This file, the main code module. +' VB FORMS: frmSplash.frm = Program "splash" form displayed while the program is running. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/29 PWR Initial version. +' 2014/06/08 PWR Updated to move already-valid and renamed datasheet files to the "web folder" location and +' to properly parse and check "operations" specified in the "names" file. +' NOTE: The operations specified are currently ignored, apart from checking for valid +' operations strings in the "names" file. The program currently always performs +' the equivalent of the "WEBMOVE" operation: +' 1) Move invalid ("bad") files to the specified "INVALID FILE MOVE FOLDER". +' 2) Rename valid DOS-encoded file names and move renamed files to the specified "WEB FOLDER". +' 3) Move already-valid datasheet files to the specified "WEB FOLDER". +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' +'Hard-coded "names" file name and location. +Public Const NAMES_FILE_NAME = "DFWDS_NAMES.txt" +'Public Const NAMES_FILE_LOC = "C:\DFWDS" + +'Constants used as aliases for code readability. +Public Const DISPLAY_MESSAGES = "True" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const HIDE_MESSAGES = "False" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const MOVE_FILE = "True" 'Used, for example, by funcDSmoveRename to control whether the file is moved or renamed. +Public Const RENAME_FILE = "False" 'Used, for example, by funcDSmoveRename to control whether the file is moved or renamed. + +'Enumerated constants for the valid operation types. +Private Enum enOperation + OPINVALID = 0 'Invalid operation type (do nothing). + COUNTOP = 1 'Only count the files of various types ("bad", files to rename, valid datasheet files...). + LISTALL = 2 'List the files of various types ("bad", files to rename, valid datasheet files...) in the log file. + LISTBAD = 3 'List only the invalid ("bad") files in the log file. + LISTRENAME = 4 'List only the renamed valid datasheet files in the log file. + INPLACE = 5 'Rename the appropriate files in the same directory they are found. + WEBMOVE = 6 'Move the renamed and already-valid datasheet files to the specified "web move" directory. + End Enum +' +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + ' + 'Define the local variables. + Dim strDSfolderName As String 'Datasheet file folder. + Dim strBadLoc As String 'Invalid ("bad") files are moved to this location in certain operations. + Dim strWebLoc As String 'Web files ("good" and "renamed" files) are moved to this location in certain operations. + Dim strOperation As String 'Operation type (count, list, "in place" or "web move", etc. + Dim strLogFileName As String 'Log file name (only). + Dim strLogFileLoc As String 'Log file folder (only). + Dim strLogFileNameLoc As String 'Log file name and location. + Dim strLogFileLine As String 'Line for the log file. + Dim lCountRenameTotal As Long 'Number of datasheet files to be renamed. + Dim lCountInvalidTotal As Long 'Number of invalid datasheet files to be moved. + Dim lCountRenameGood As Long 'Number of datasheet files renamed that have been moved successfully. + Dim lCountInvalidGood As Long 'Number of invalid datasheet files that have been moved successfully. + Dim lCountAll As Long 'Total number of files in datasheet file directory. + Dim lCountValidTotal As Long 'Number of "good" datasheet files that do not need to be renamed. + Dim lCountValidGood As Long 'Number of "good" datasheet files that have been moved successfully. + Dim iLogFileHandle As Integer 'Log file number ("file handle"). + Dim dStartTime As Double 'Program start time. + Dim dEndTime As Double 'Program start time. + Dim strStartDate As String 'Date that the program is run. + Dim iOldMouse As Integer 'Store previous mouse state. + + On Error GoTo ErrorHandler + + 'Display program (splash) form. + frmSplash.Show + frmSplash.Refresh + + 'Get next valid file number (file + 'handle) for the log file. + iLogFileHandle = FreeFile + + 'Set start time. + dStartTime = Timer + + 'Initialize counts. + lCountRenameTotal = 0 + lCountInvalidTotal = 0 + lCountRenameGood = 0 + lCountInvalidGood = 0 + lCountValidTotal = 0 + lCountValidGood = 0 + lCountAll = 0 + + 'Check for "names" file and read values from the file. End the + 'program if there is a problem with the "names" file. + If Not (functionNamesFileReadOK(strDSfolderName, strLogFileName, strLogFileLoc, strBadLoc, strWebLoc, strOperation) = True) Then + End 'End the program. + End If + + 'Get starting date of program (for log file name and header) + 'and set full log file name based on the formatted date. + strStartDate = Format(Date$, "yyyy_mm_dd") 'Get starting date of program. + strLogFileName = strLogFileName & "_" & strStartDate & ".log" 'Get log file name with date. + + 'Open log file. + If (funcOpenLogFile(strLogFileName, strLogFileLoc, iLogFileHandle) = False) Then + Close #iLogFileHandle 'Close the log file. + Call subFileOpenMessage(strLogFileNameLoc) 'Display error message. + End 'Exit the program. + End If + + 'Write log file header. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Date: " & strStartDate & ", Time: " & Time$ + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + 'Call routine to process files in datasheet folder. + Call subProcessDSfolder(strOperation, strDSfolderName, strBadLoc, strWebLoc, strLogFileNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood, lCountValidTotal, lCountValidGood, _ + lCountAll) + + 'Write log file footer information and close the log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total files processed = " & lCountAll + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Bad files to be moved = " & lCountInvalidTotal & vbCrLf & _ + "Bad files successfully moved = " & lCountInvalidGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Files to be renamed = " & lCountRenameTotal & vbCrLf & _ + "Files successfully renamed = " & lCountRenameGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Valid (unchanged) files = " & (lCountValidTotal) & vbCrLf & _ + "Valid files successfully moved = " & (lCountValidGood) + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total good datasheet files = " & (lCountValidTotal + lCountRenameTotal) & vbCrLf & _ + "Good files successfully moved = " & (lCountValidGood + lCountRenameGood) + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + dEndTime = Timer 'Set end time. + strLogFileLine = "Elapsed time = " & Format(dEndTime - dStartTime, "##0.0") & " seconds" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + Close #iLogFileHandle + + 'Unload the program (splash) form. + Unload frmSplash 'Unload the network-copy program splash screen. + + End 'Exit program. + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Close #iLogFileHandle + MsgBox ("Error in ""Main"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End 'Exit program. +End Sub + +Public Function functionNamesFileReadOK(ByRef strDSfolderName As String, ByRef strLogFileName As String, _ + ByRef strLogFileLoc As String, ByRef strBadLoc As String, ByRef strWebLoc As String, _ + ByRef strOperation As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function checks for the presence of the "names" file holding the locations of the datasheet + 'file folder, the invalid file "move" folder, and the log file folder for the program as well as + 'the log file name. If the "names" file is found, this function reads lines from the file and puts + 'the values obtained in the appropriate variables that are returned, by reference, for use in other + 'routines. The validates the parameter names against the expected names for the appropriate lines + 'in the "names" folder, and for the folder values, validates the existence of the folders. The + 'function returns "True" if the "names" file is found and the parameter names and values read from + 'the names file can be validated against the expected values or the existence of the appropriate + 'folders. The function returns "False" if the "names" file cannot be found or read, if any of the + 'parameter names or values cannot be validated, or if there is any other problem in the function. + ' + 'NOTE: The log file name parameter value is validated outside of this function, when the log file + ' is first opened. + ' + ' Inputs: + ' All paramters are by-reference outputs whose values are read from the "names" file. + ' Outputs: + ' Error messages, log file entries. + ' Function return: The function returns "True" if the "names" file is found and can be + ' read and all of the parameters and values are appropriate. + ' strDSfolderName: Passes the name of the datasheet file folder by reference from + ' the validated value read from the "names" file. + ' strLogFileName: Passes the name of the log file by reference from the validated + ' value read from the "names" file. + ' strLogFileLoc: Passes the name of the log file folder by reference from the + ' validated value read from the "names" file. + ' strBadLoc: Passes the name of the invalid ("bad") file folder by reference from + ' the validated value read from the "names" file. + ' strWebLoc: Passes the name of the "Web" file folder by reference from + ' the validated value read from the "names" file. + ' strOperation: Passes the name of the operation by reference from + ' the validated value read from the "names" file. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strNamesFileLoc As String 'Location (folder) of the "names" file. + Dim strNamesFileNameLoc As String 'Name and location (folder) of the "names" file. + Dim strMessageString As String 'String for error message from reading "names" file lines. + Dim strParmName As String 'Parameter name read from the "names" file. + Dim strParmValue As String 'Parameter value read from the "names" file. + Dim strParmNameExpected As String 'Parameter value expected from the "names" file. + Dim iLineNumber As Integer 'Number of line read from the "names" file. + Dim iNamesFileHandle As Integer 'File number (file "handle") of the "names" file. + Dim objFSO As FileSystemObject 'File system object for "names" file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get next valid file number (file + 'handle) for the "names" file. + iNamesFileHandle = FreeFile + + 'Initialize. + strMessageString = "" 'Initialize as null (blank) string. + functionNamesFileReadOK = True 'Initialize as "all file entries read OK". + strDSfolderName = "" 'Set string to null. + strLogFileName = "" 'Set string to null. + strLogFileLoc = "" 'Set string to null. + strBadLoc = "" 'Set string to null. + strWebLoc = "" 'Set string to null. + strOperation = "" 'Set string to null. + + 'Set file name and location from hardcoded constants. + 'strNamesFileLoc = NAMES_FILE_LOC 'Set "names" file folder to defined location. + strNamesFileLoc = CurDir 'Set "names" file folder to defined location. + If Right$(strNamesFileLoc, 1) <> "\" Then strNamesFileLoc = strNamesFileLoc & "\" 'Add trailing backslash (if needed). + strNamesFileNameLoc = strNamesFileLoc & NAMES_FILE_NAME 'Add "names" file name to folder. + + 'Check for existence of "names" file folder. + If Not funcFolderExists(strNamesFileLoc, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strNamesFileLoc & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Check for existence of the "names" file. + If Not (objFSO.FileExists(strNamesFileNameLoc)) Then + 'File not found. Post error return, display + 'error message, and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The ""names"" file: " & strNamesFileNameLoc & " was not found!" & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Destroy the file system object (it is + 'not used later in the function). + Set objFSO = Nothing + + 'Open the "names" file for input (reading line by line). + Open strNamesFileNameLoc For Input As iNamesFileHandle + + 'Read lines of the "names" file and check parameter names and values. + For iLineNumber = 1 To 6 + 'Set expected parameter names. + If (iLineNumber = 1) Then strParmNameExpected = "DATASHEET FOLDER NAME" + If (iLineNumber = 2) Then strParmNameExpected = "INVALID FILE MOVE FOLDER" + If (iLineNumber = 3) Then strParmNameExpected = "LOG FILE NAME" + If (iLineNumber = 4) Then strParmNameExpected = "LOG FILE FOLDER" + If (iLineNumber = 5) Then strParmNameExpected = "WEB FOLDER" + If (iLineNumber = 6) Then strParmNameExpected = "OPERATION" + 'Get line of two comma-separated values and put into variables. + Input #iNamesFileHandle, strParmName, strParmValue + 'Trim the values read. + strParmName = Trim(strParmName) + strParmValue = Trim(strParmValue) + If (strParmName = strParmNameExpected) Then + 'Expected parameter name is found. + If ((iLineNumber = 3) Or (iLineNumber = 6)) Then + 'Log file partial name (line 3) or operation type (line 6). + 'No modification of parameter is required. + Else + 'The parameter is a location (folder) parameter. Add a trailing backslash, + 'if necessary, and check if the folder exists. + If Right$(strParmValue, 1) <> "\" Then strParmValue = strParmValue & "\" + 'Check if folder exists. + If Not funcFolderExists(strParmValue, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strParmValue & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + End If + Else + 'The parameter name read from the "names" file does not match the + 'expected value. Post error return, display error message, + 'and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The parameter read from the ""names"" file" & vbCrLf & _ + "does not match the expected value!" & vbCrLf & _ + "Parameter read: " & strParmName & vbCrLf & _ + "Parameter expected: " & strParmNameExpected & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Set parameter values to appropriate variables. + If (iLineNumber = 1) Then strDSfolderName = strParmValue + If (iLineNumber = 2) Then strBadLoc = strParmValue + If (iLineNumber = 3) Then strLogFileName = strParmValue + If (iLineNumber = 4) Then strLogFileLoc = strParmValue + If (iLineNumber = 5) Then strWebLoc = strParmValue + If (iLineNumber = 6) Then strOperation = strParmValue + Next iLineNumber + + 'Check for valid operation string. + If (funcGetOPnumber(strOperation) = 0) Then + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Invalid operation name =" & strOperation & vbCrLf & _ + "No file operations performed!" & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End If + + 'Close the "names" file. + Close #iNamesFileHandle + + Exit Function 'Exit the function (before the error handler) if no error. +ErrorHandler: + Close #iNamesFileHandle 'Close the "names" file. + Set objFSO = Nothing 'Destroy the file system object. + functionNamesFileReadOK = False 'Error return value. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcOpenLogFile(ByVal strLogFileName As String, ByVal strLogFileLoc As String, _ + ByVal iLogFileHandle As Integer) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function opens the log file specified by the passed file name and folder for append using the + 'passed file "handle". The function returns "True" if there is no problem opening the file, and + 'returns "False" if any problem occurs. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFullFileName As String + + On Error GoTo ErrorHandler + + 'Make sure the folder name includes a trailing "\", then create + 'full file name (file name including folder) and open the file + 'for append. + If Right$(strLogFileLoc, 1) <> "\" Then strLogFileLoc = strLogFileLoc & "\" + strFullFileName = strLogFileLoc & strLogFileName 'Create full file name (name with location). + Open strFullFileName For Append As iLogFileHandle 'Open log file for append. + funcOpenLogFile = True 'Return value indicating no problems opening the file. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcOpenLogFile = False 'Error value. + MsgBox ("Error in ""funcOpenLogFile"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subFileOpenMessage(ByVal strLogFileNameLoc As String) + '---------------------------------------------------------------------------------------------------- + 'Subroutine to display error message about opening the log file using the passed full log file name + '(the file name complete with its directory location). + '---------------------------------------------------------------------------------------------------- + ' + MsgBox ("Error opening log file: " & strLogFileNameLoc & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcFolderExists(ByVal strFolderName As String, ByVal bDisplayErrMsg As Boolean) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed folder exists, and "False" if it does not, or there is + 'any other problem with the function. The passed flag displays a "file not found" message if "True", + 'or skips the message if "false" (for example, if a calling routine has its own error message). + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Make sure the folder name includes a trailing "\". + If Right$(strFolderName, 1) <> "\" Then strFolderName = strFolderName & "\" + + 'Check whether the folder exists. + If Not objFSO.FolderExists(strFolderName) Then + funcFolderExists = False 'Return value for "folder not found". + If (bDisplayErrMsg) Then + 'Display error message if the flag is "True". + MsgBox ("Folder not found: " & strFolderName & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End If + Else + funcFolderExists = True 'Return value for "folder found". + End If + + Set objFSO = Nothing 'Destroy file system object. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcFolderExists = False 'Error value. + Set objFSO = Nothing 'Destroy file system object. + MsgBox ("Error in ""funcFolderExists"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subProcessDSfolder(ByVal strOperation As String, ByVal strDSfolderName As String, ByVal strDSbadLocation As String, _ + ByVal strWebLoc As String, ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer, ByRef lCountInvalidTotal As Long, _ + ByRef lCountRenameTotal As Long, ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long, _ + ByRef lCountValidTotal As Long, ByRef lCountValidGood As Long, ByRef lCountAll As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the datasheet (and possibly other) files in the passed folder. The subroutine + 'initializes counts, writes a header to the log file specified by the passed log file name and location, + 'and performs a directory listing of the passed folder, processing each file name through using + 'the "subProcessDSfile" subroutine to determine whether the file is an invalid ("bad") datasheet file. + 'Depending on the passed "operation", the subroutine moves the "bad" files to the passed "bad" file + 'location, renames and moves the files with valid DOS-encoded datasheet file names to the passed "Web" + 'folder, and also moves the files with valid datasheet names that do not need to be renamed to the + 'passed "Web" folder. All of these actions (or "list" or "count" operations and/or data) are logged to + 'the log file. + ' + ' Inputs: + ' strOperation: Datasheet file operation ("list" or "count" type operations, "in place" rename + ' or "web move" for valid and renamed datasheet files). + ' strDSfolderName: Source datasheet file folder location. + ' strDSbadLocation: Directory location where invalid ("bad") files are moved. Invalid files include + ' non-text files and files with names that do not match the format for the Dataforth + ' website. + ' strWebLoc: Directory location where valid and renamed datasheet files are moved. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountValidTotal: Passes initial count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes initial count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountAll: Passes initial count of all files found in the datasheet folder to + ' the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid ("bad") datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid ("bad") datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidTotal: Passes count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountAll: Passes the count of all files found in the datasheet file folder + ' back to the calling routine by reference for status displays, etc. + ' Also used, on first call, to pass the initial count from the calling + ' routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFileName As String + Dim strFullFileName As String + Dim strDirSpec As String + + On Error GoTo ErrorHandler + + 'Initialize. + lCountInvalidTotal = 0 + lCountRenameTotal = 0 + lCountInvalidGood = 0 + lCountRenameGood = 0 + lCountValidTotal = 0 + lCountValidGood = 0 + lCountAll = 0 + + 'Set Dir$ function specification (directory path and search criteria). + 'NOTE: Search criteria is "all files", rather than just "text files" + ' since text files are validated later as part of the specific + ' datasheet file validation process. + If Right$(strDSfolderName, 1) <> "\" Then + strDirSpec = strDSfolderName & "\*.*" 'Add trailing backslash (if needed) and search for any file. + Else + strDirSpec = strDSfolderName & "*.*" 'Add search for any text file. + End If + 'strFileName = Dir$(strDirSpec, vbNormal) + + 'Loop through each file in the folder + 'Do While (strFileName <> "") + Do + 'Loop through all matching files in directory. + 'strFileName = Dir$ + strFileName = Dir$(strDirSpec, vbNormal) + If (strFileName <> "") Then + Call subProcessDSfile(strOperation, strFileName, strDSfolderName, strDSbadLocation, strWebLoc, _ + strDSlogNameLoc, iLogFileHandle, lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood, _ + lCountValidTotal, lCountValidGood) + lCountAll = lCountAll + 1 'Increment total count. + frmSplash.lblFileCount.Caption = lCountAll + frmSplash.lblCurrentFile.Caption = strFileName + frmSplash.lblFileCount.Refresh + frmSplash.lblCurrentFile.Refresh + Else + Exit Do + End If + Loop + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfolder"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subProcessDSfile(ByVal strOperation As String, ByVal strDSFileName As String, ByVal strDSfolderName As String, _ + ByVal strDSbadLocation As String, ByVal strDSwebFolderName As String, ByVal strDSlogNameLoc As String, _ + ByVal iLogFileHandle As Integer, ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long, _ + ByRef lCountValidTotal As Long, ByRef lCountValidGood As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the passed file name. If it is determined to be an invalid name for the Dataforth + 'website, the file is moved to the passed directory location and this action is recorded in a log file + 'whose name and location is also passed as a parameter. If the file name matches the format of "encoded" + 'datasheet file names from the DOS test programs, the file is renamed to the appropriate "unencoded" + 'datasheet file name and this action is also recorded to the specified log file. The subroutine posts + 'error messages for problems that may be encountered during file processing, and passes file counts + '(total files found to be renamed or moved, files successfully rename or moved) to the calling routine. + ' + ' Inputs: + ' strOperation: Datasheet file operation ("list", "count", "in place", "web move", etc.). + ' strDSfileName: Datasheet file name. + ' strDSbadLocation: In certain operations, this is the directory location where invalid ("bad") + ' files are moved. Invalid files include non-text files and files with names + ' that do not match the format for the Dataforth website. + ' strDSwebFolderName: In certain operations, this is the directory location where valid or renamed + ' files are moved. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid ("bad") datasheet files to the + ' subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountValidTotal: Passes initial count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes initial count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidTotal: Passes count of valid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountValidGood: Passes count of successfully moved valid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strWorkOrderNum As String 'Work order number. + Dim strFullFileName As String 'Full file name (including extension). + Dim strFileNameOnly As String 'File name (only). + Dim iDashLoc As Integer 'Dash location in file name (only) string. + Dim iFNOlength As Integer 'Length of file name (only) string. + Dim strWOdecoded As String 'Work order number. + + On Error GoTo ErrorHandler + + 'Get uppercase-only version of the full file name. + 'This is necessary for later processing of the + 'datasheet files (including determining whether + 'they are validly-named datasheet files). + strFullFileName = UCase$(strDSFileName) + + 'Get the file name (only). This should be the (encoded + 'or unencoded) module serial number. Note that the + 'function requires a full file name already in + 'all-UPPERCASE. + strFileNameOnly = funcGetFileNameOnly(strFullFileName) + + 'Check for text file. + If (strFileNameOnly = "") Then + 'Not a text file (null return from funcGetFileNameOnly). + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-text file. + End If + + 'Check for valid dash location (and/or existence) and a valid dash number. + iDashLoc = funcGetDashLoc(strFileNameOnly) 'Get dash location. + + 'Check for valid location. + If Not (funcGetDashLoc(strFileNameOnly) > 0) Then + 'Dash (or dash number) is not valid. + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + + 'Parse work order# (characters to the left of + 'the dash) from the serial number string. + strWorkOrderNum = Left$(strFileNameOnly, iDashLoc - 1) + + If (funcIsAllNumbers(strWorkOrderNum) = True) Then + 'Work order number string is all numbers, + 'check for leading "0". + If (Left$(strWorkOrderNum, 1) = "0") Then + 'Leading "0" in all-numeric work order number. Work order number is not valid. + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + Else + 'Valid work order number. Move file to "web folder". + lCountValidTotal = lCountValidTotal + 1 'Increment already-valid file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSwebFolderName, strDSlogNameLoc, iLogFileHandle) Then + lCountValidGood = lCountValidGood + 1 'Increment already-valid files moved successfully count. + End If + End If + Else + 'Work order string is not all numbers. Check if + 'it is matches the format of a DOS-encoded work + 'order number. + If (funcISrenameWO(strWorkOrderNum) = True) Then + 'DOS-encoded work order number. Rename file + 'to unencoded datasheet file name. + lCountRenameTotal = lCountRenameTotal + 1 'Increment "renamed" file count. + If funcDSmoveRename(RENAME_FILE, strFullFileName, strDSfolderName, "", strDSlogNameLoc, iLogFileHandle) Then + 'File successfully renamed in place. Move to "web folder". + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSwebFolderName, strDSlogNameLoc, iLogFileHandle) Then + lCountRenameGood = lCountRenameGood + 1 'Increment "renamed" file processed correctly ("good") count. + End If + End If + Else + 'Not a DOS-encoded work order number. Work order number is not valid. + 'Move file to the specified "bad" file location and log action to specified log file. + lCountInvalidTotal = lCountInvalidTotal + 1 'Increment "bad" file count. + If funcDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSbadLocation, strDSlogNameLoc, iLogFileHandle) Then + lCountInvalidGood = lCountInvalidGood + 1 'Increment "bad" file processed correctly ("good") count. + End If + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + End If + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcGetFileNameOnly(ByVal strFullFileName As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned + 'if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem (such as a blank file name passed to the function), a null string + 'is returned. + ' + 'NOTE: The passed full file name must be in all-UPPERCASE for the ".TXT" check to work. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strFullFileName) 'Get length of the full file name. + strSerial = Left$(strFullFileName, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcGetFileNameOnly = strSerial + Else + funcGetFileNameOnly = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcGetFileNameOnly = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcGetFileNameOnly = "" 'Error value. + MsgBox ("Error in ""funcGetFileNameOnly"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Function funcIsAllNumbers(ByVal strTestString As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'Function that checks whether the passed string consists of only numerical characters. The function + 'returns "True" if each character in the string is a number, and "False" if any character is not + 'a number or if there is some other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strChar As String + Dim iDx As Integer + + On Error GoTo ErrorHandler + + 'Initialize to "all numbers" value. + funcIsAllNumbers = True + + If (strTestString = "") Then + 'Invalid Work Order number string (null string). + funcIsAllNumbers = False 'Set "not all numbers" value. + Else + For iDx = 1 To Len(strTestString) 'Loop from 1st character to last character of string. + 'See if the next character is a non-number. + strChar = Mid$(strTestString, iDx, 1) 'Get next character. + If ((strChar < "0") Or (strChar > "9")) Then 'Character is not "0" through "9". + funcIsAllNumbers = False 'Set "not all numbers" value. + Exit For 'Exit the loop (no need to continue after first non-number). + End If + Next iDx + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsAllNumbers = False 'Error ("not all numbers") value. + MsgBox ("Error in ""funcIsAllNumbers"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetDashLoc(ByVal strFileNameOnly As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the dash ("-") location in the passed file name (only) string. It returns + 'an error value of "0" if no dash is found, or more than one dash is found, if there are more + 'than one characters after the dash, and if any of the characters after the dash are not a + 'number, or if there are any other problems in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + Dim strDashNum As String 'Dash number string. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strFileNameOnly) 'Length of file name (only) string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strFileNameOnly, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strFileNameOnly, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end (dash number + 'more than two characters, or less than one). + funcGetDashLoc = 0 'Error value (invalid dash). + Else + 'Dash number is one or two characters. Get for an all-number dash number. + strDashNum = Mid$(strFileNameOnly, iDashLocL + 1, iSTRlength - iDashLocL) + If (funcIsAllNumbers(strDashNum) = True) Then + 'Dash number is all numbers. + funcGetDashLoc = iDashLocL 'Good value (valid dash). + Else + 'Dash number is not valid (not all numbers). + funcGetDashLoc = 0 'Error value (invalid dash). + End If + End If + Else + 'More than one dash in the serial string. + funcGetDashLoc = 0 'Error value (invalid dash). + End If + + Exit Function 'Exit before error handler. +ErrorHandler: + funcGetDashLoc = 0 'Error (not valid) value. + MsgBox ("Error in ""funcIsValidDash"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDecodeWOchar(ByVal strWOnum As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns a two-character string decoded from the first character of the + 'passed work order number string. If the first character is "A" through "J", the + 'function returns "10" through "19", respectively, which represents the values that + 'are encoded in valid DOS-encoded datasheet file names. If the first character is + 'not "A" or "J" or a letter in between, or if there is some problem in the function, + 'the function returns a null string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strFirstChar As String 'First character in passed work order number string. + + On Error GoTo ErrorHandler + + If (strWOnum = "") Then + 'Null string, return error value (null string). + funcDecodeWOchar = "" 'Error value. + Else + 'String has at least one character, check for "A" through "J". + strFirstChar = Left$(strWOnum, 1) 'Get first character of passed work order number. + If (strFirstChar = "A") Then + funcDecodeWOchar = "10" 'Decode of first character. + ElseIf (strFirstChar = "B") Then + funcDecodeWOchar = "11" 'Decode of first character. + ElseIf (strFirstChar = "C") Then + funcDecodeWOchar = "12" 'Decode of first character. + ElseIf (strFirstChar = "D") Then + funcDecodeWOchar = "13" 'Decode of first character. + ElseIf (strFirstChar = "E") Then + funcDecodeWOchar = "14" 'Decode of first character. + ElseIf (strFirstChar = "F") Then + funcDecodeWOchar = "15" 'Decode of first character. + ElseIf (strFirstChar = "G") Then + funcDecodeWOchar = "16" 'Decode of first character. + ElseIf (strFirstChar = "H") Then + funcDecodeWOchar = "17" 'Decode of first character. + ElseIf (strFirstChar = "I") Then + funcDecodeWOchar = "18" 'Decode of first character. + ElseIf (strFirstChar = "J") Then + funcDecodeWOchar = "19" 'Decode of first character. + Else + 'Not "A" through "J" + funcDecodeWOchar = "" 'Error value. + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcDecodeWOchar = "" 'Error value. + MsgBox ("Error in ""funcDecodeWOchar"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcISrenameWO(ByVal strWOnumber As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed work order number matches the format of a DOS-encoded + 'work order number (for work orders above the value of "99,999"). A DOS-encoded work order number + 'will be five characters long, start with "A" through "J", and have all numbers for the remaining + 'characters. The function will return "False" if any of these conditions are not true, or there is + 'any other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLastFour As String + Dim strFirstOne As String + + On Error GoTo ErrorHandler + + If (Len(strWOnumber) <> 5) Then + 'Not five characters long. + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strFirstOne = UCase$(Left$(strWOnumber, 1)) + If ((strFirstOne < "A") Or (strFirstOne > "J")) Then + 'First character not "A" through "J". + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strLastFour = Right$(strWOnumber, 4) + If (funcIsAllNumbers(strLastFour) = True) Then + funcISrenameWO = True 'Set "valid rename string" value. + Else + 'Last four characters not all numberss. + funcISrenameWO = False 'Set "not a valid rename string" value. + End If + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcISrenameWO = False 'Error value (not valid "rename" string). + MsgBox ("Error in ""funcISrenameWO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDSmoveRename(ByVal bMoveFile As Boolean, ByRef strDSFileName As String, ByVal strDSfolderName As String, _ + ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer) As Boolean + '------------------------------------------------------------------------------------------------------------- + 'Function that moves or renames the file specified by the passed file name and datasheet file folder. If the + 'move/rename parameter ("bMoveFile") is "True", the file is moved to the directory specified by the + 'passed "move location" folder name. If the parameter is "False", the file is renamed from the DOS-encoded + 'name to the unencoded datasheet file name. In both cases, the "move" or "rename" is accomplished by copying the + 'file to the new name or location, and then deleting the old file if nothing has gone wrong. All actions, + 'including successful moves or renames, unsuccessful file copies, or unsuccessful file deletions, are + 'recorded in a log file whose name and location, as well as its file number (file "handle"), are passed + 'as parameters. The function returns "True" if there are no problems, and "False" if there are any problems. + 'The function also returns (by reference) the new datasheet file name of renamed files. + ' + 'NOTE: Since the existence of all of the relevant directories is verified by one of the calling routines + ' directory checking is not repeated here to save program time (since this function is called for + ' every relevant file). + ' + ' Inputs: + ' bMoveFile: This parameter is "True" to move the specified file to the "move" + ' folder or "False" to rename the specified file from the + ' DOS-encoded work order number (for values above "99,999") to the + ' unencoded work order number (file name matching the module serial + ' number contained within the datasheet file). + ' strDSFileName: Full file name of the file to be moved (includes file extension + ' but not folder location). + ' strDSfolderName: Datasheet folder location. + ' strDSmoveLocation: Directory location where the file is to be moved. + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' iLogFileHandle: File "handle" (file number) for log file. + ' Outputs: + ' Error messages, log file entries. + ' strDSFileName: Full file name of the renamed datasheet file (includes file extension + ' but not folder location). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLogFileLine As String 'String for a line of information for the log file. + Dim strRenameFileName As String 'Full file name (name and extension) for the renamed (unencoded) datasheet file name. + Dim strDSFileNameLoc As String 'Full file name (name and extension) and folder of the file in the datasheet folder. + Dim strRenameFileNameLoc As String 'Full file name (name and extension) and folder for the renamed (unencoded) datasheet file name. + Dim strRenameFirstChars As String 'First character of file to be renamed, or (decoded) first two characters of renamed file. + Dim iLenFullFileName As Integer 'Length of the full file name of the file to be renamed. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + + 'Initialize function return. + funcDSmoveRename = False 'Initialize to bad return (set to good at end if there are no problems). + + 'Initialize strings to null. + strLogFileLine = "" + strRenameFileName = "" + strDSFileNameLoc = "" + strRenameFileNameLoc = "" + strRenameFirstChars = "" + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Create the full file name and location from the full file + 'name and the folder location. First, add a trailing + 'backslash, if needed, to the folder location. + If Right$(strDSfolderName, 1) <> "\" Then strDSfolderName = strDSfolderName & "\" + strDSFileNameLoc = strDSfolderName & strDSFileName + + 'If the file needs to be renamed, create the full "rename" file name + '(file name and extension) from the original DOS-encoded name, then + 'create the full name/location (file name and folder location). + If Not (bMoveFile) Then + 'File to be renamed. Decode first character of full file name. + strRenameFirstChars = Left$(strDSFileName, 1) 'Get first character of file to be renamed. + iLenFullFileName = Len(strDSFileName) 'Get the length of the full file name of the file to be renamed. + 'Use the "decode work order character" function to decode the first character of the full + 'file name of the file to be renamed (note, the function name implies the passed string + 'is the work order number only, but since the function only uses the first character of + 'the string, it also works for the full file name). + strRenameFirstChars = funcDecodeWOchar(strDSFileName) 'Get decoded first two characters of full file name. + 'Create the renamed file name, by combining the new decoded characters with the characters of the full + 'datasheet file name to be renamed, but skipping the first character. + strRenameFileName = Right$(strDSFileName, iLenFullFileName - 1) 'Get full file name minus the first character. + strRenameFileName = strRenameFirstChars & strRenameFileName 'Create full rename file name by adding decoded characters. + strRenameFileNameLoc = strDSfolderName & strRenameFileName 'Create full rename file name/location by adding folder. + 'NOTE: This is the same folder as the original + ' datasheet file. + strDSFileName = strRenameFileName 'Return renamed datasheet file name. + End If + + 'Create "could not copy" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the CopyFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "copy good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not copy" message. + strLogFileLine = "Could not copy file: " & strDSFileNameLoc & " to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not copy file: " & strDSFileNameLoc & " to: " & strRenameFileName + End If + + 'Copy the file in the datasheet folder. For moves, copy to the "move" directory. + 'For rename, copy to a new name in the same folder. File copy parameters: + 'source (full file name/loc), destination (folder + 'only or full (rename) file name/loc), "True" for + 'overwrite if a file of same name already exists + 'in the destination. + If (bMoveFile) Then + 'Move invalid file. Start by copying to new folder location. + Call objFSO.CopyFile(strDSFileNameLoc, strDSmoveLocation, True) + Else + 'Rename DOS-encoded datasheet file. Start by copying to name in same folder. + Call objFSO.CopyFile(strDSFileNameLoc, strRenameFileNameLoc, True) + End If + + 'Create "could not delete" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the DeleteFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "delete good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not delete" message. + strLogFileLine = "Could not delete file: " & strDSFileNameLoc & " after copy to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not delete file: " & strDSFileNameLoc & " after copy to: " & strRenameFileName + End If + + 'Delete the invalid file in the datasheet folder. + 'File delete parameters: full file/loc, "True" + 'for "force" (ignore read-only). + Call objFSO.DeleteFile(strDSFileNameLoc, True) + + 'Since there were no problems to this point (no jump to the error handler), + 'create "successfully moved" or "successfully renamed" message and write + 'the message to the log file. + If (bMoveFile) Then + strLogFileLine = "Moved file: " & strDSFileNameLoc & " to: " & strDSmoveLocation + Else + strLogFileLine = "Renamed file: " & strDSFileNameLoc & " to: " & strRenameFileName + End If + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + funcDSmoveRename = True 'Set Good function return. + + Set objFSO = Nothing 'Destroy file system object. + + Exit Function ' Exit before error handler. +ErrorHandler: + Print #iLogFileHandle, strLogFileLine 'Write previously-generated error message to log file. + Set objFSO = Nothing 'Destroy file system object. + 'NOTE: Since this function processes many files, errors should be posted (only) to the log + ' file, NOT to the screen. Therefore, the following two lines (single line of code) + ' are (is) commented out. + 'MsgBox ("Error in ""funcDSmoveRename"" = " & Err.Description & vbCrLf & vbCrLf & _ + ' "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetOPnumber(ByVal strOPname As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the appropriate enumerated operation number from the passed + 'operation string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iReturn As Integer + + On Error GoTo ErrorHandler + + If (strOPname = "COUNT") Then + iReturn = 1 + ElseIf (strOPname = "LISTALL") Then + iReturn = 2 + ElseIf (strOPname = "LISTBAD") Then + iReturn = 3 + ElseIf (strOPname = "LISTRENAME") Then + iReturn = 4 + ElseIf (strOPname = "INPLACE") Then + iReturn = 5 + ElseIf (strOPname = "WEBMOVE") Then + iReturn = 6 + Else + iReturn = 0 'Error value. + MsgBox ("Error in ""funcGetOPnumber"" = " & vbCrLf & _ + "Invalid operation = " & strOPname & vbCrLf & _ + "Function return = " & iReturn & vbCrLf), vbCritical + End If + + funcGetOPnumber = iReturn 'Set function return. + + Exit Function ' Exit before error handler. +ErrorHandler: + iReturn = 0 'Error value. + funcGetOPnumber = iReturn 'Set function return. + MsgBox ("Error in ""funcGetOPnumber"" = " & Err.Description & vbCrLf & _ + "Function return = " & iReturn & vbCrLf), vbCritical +End Function + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.vbp new file mode 100644 index 0000000..540b885 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\Windows\SysWOW64\MSSTDFMT.DLL#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao350.dll#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; tabctl32.ocx +Module=A_Main; DFWDS.bas +Form=frmSplash.frm +Startup="Sub Main" +HelpFile="" +Title="DFWDS" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.vbw new file mode 100644 index 0000000..f62f99f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS_NAMES.txt b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS_NAMES.txt new file mode 100644 index 0000000..cc4dab1 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/DFWDS_NAMES.txt @@ -0,0 +1,80 @@ +DATASHEET FOLDER NAME,X:\Test_Datasheets +INVALID FILE MOVE FOLDER,X:\Bad_Datasheets +LOG FILE NAME,DFWDS +LOG FILE FOLDER,X:\Datasheets_Log +WEB FOLDER,X:\For_Web +OPERATION,WEBMOVE + +Last updated: 2015-06-08 + +The first six lines of this file are folder and file names required by +the Dataforth Website Datasheet program (DFWDS.exe). Each line consists +of the parameter name (in all CAPS), followed by a comma, followed by +the file or folder name (not in quotes) or operation. A space is +allowed after the comma separator. + +The six lines parameter lines must contain only the allowed parameters +and data, in this specified format, for the program to operate properly. +Any lines below these six lines are not read by the program, and can +consist of comments or instructions (such as these). + +The location and name of this file (usually C:\DFWDS\DFWDS_NAMES.TXT) is +hardcoded in the program. + +Descriptions of the six required lines (along with the required parameter +names) are shown below: + +First line: +----------- +DATASHEET FOLDER NAME: This is the location of the folder containing the +datasheet files that will eventually be copied to the Dataforth website. + +Second line: +------------ +INVALID FILE MOVE FOLDER: This is the location of the folder to which +invalid files in the datasheet folder will be moved. + +Third line: +----------- +LOG FILE NAME: This is the name of the file that logs the operation of the +Dataforth Website Datasheet program (DFWDS.exe), including invalid file +moves and datasheet file renaming. NOTE: This is the file name (only), +and does NOT include the ".log" extension. + +Fourth line: +------------ +LOG FILE FOLDER: This is the location of the folder containing the log +file for the DFWDS.exe program. + +Fifth line: +WEB FOLDER: This is the location of the folder to which the valid +datasheet files (including renamed files) are moved if the "OPERATION" +parameter (see below) is "WEBMOVE". + +Sixth line: +----------- +OPERATION: This parameter controls the operation of the program, and +can only be one of the values described below: +------------------------------------- +COUNT causes the program to only count the invalid files +and files that should be renamed. + +LISTALL causes the program to list all of the files found in the +datasheet folder. + +LISTBAD causes the program to list all of the invalid ("bad") files +found in the datasheet folder. + +LISTRENAME causes the program to list all of the datasheet files in +the datasheet folder that have DOS-encoded names that need to be +renamed to match the module serial number contained in the file. + +INPLACE renames the appropriate files in their current directory +(specified by the "DATASHEET FOLDER NAME" parameter - see above), but +moves the invalid files to the directory specified by the +"INVALID FILE MOVE FOLDER" parameter (see above). + +WEBMOVE moves the invalid files to the "INVALID FILE MOVE FOLDER" +directory, but also moves the valid datasheet files (including those +that have been renamed) to the folder specified by the "WEB FOLDER" +parameter (see above). \ No newline at end of file diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/_Working/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.bas new file mode 100644 index 0000000..4a1466d --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.bas @@ -0,0 +1,501 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2014_09_24" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/24 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = this file, main code module. +' VB FORMS: frmDBselect.frm = form to select directory and .DAT file for model database. +' frmDATAselect.frm = form to select .DAT file for stored model datasheet data and print +' text file datasheets. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/24 PWR Initial version. +' +' ------------------------------------------------------------------------------------------------------------------------------------- + +'---------------------------------------------------------------------------------------------------- +' Hard-coded values. +'---------------------------------------------------------------------------------------------------- +Public Const PRINTSHEET_SUBDIR = "PRINT" ' Hardcoded printed datasheet directory (below folder with .DAT files). +Public Const NUMPTS = 5 ' Hardcoded number of points for accuracy/linearity measurements. +Public Const NUMTESTS = 20 ' Hardcoded maximum array index (# of stored tests) for STATUS (strTestDATSTRING) and other arrays. + +' Global variables. +Public strDBFILEname As String ' Global variable to hold database (.DAT) file name. +Public strDBFILEfolder As String ' Global variable to hold database (.DAT) file folder. +Public strDATFILEname As String ' Global variable to hold stored datasheet data (.DAT) file name. +Public strDATFILEfolder As String ' Global variable to hold stored datasheet data (.DAT) file folder. +Public iFileCount As Integer ' Count of number of text datasheet files "printed". +Public iDupCount As Integer ' Count of number of text datasheet files "printed" over an existing file. +Public bDisplayMessages As Boolean ' Flag, "True" to display error messages in various functions and subroutines. +Public bPrintFailingUnits As Boolean ' Flag, "True" to also print text log files from failing units. + +' Global arrays. +Public strTestNAMES(1 To NUMTESTS) As String ' Global array for the Final Test test names. +Public strTestUNITS(1 To NUMTESTS) As String ' Global array for the Final Test test units. +Public strTSPEC(1 To NUMTESTS) As String ' Global array for the Final Test test limits strings for printed datasheet. +Public strMODNAME As String ' Global variable for module model name: "SCM5B30-1419", for example. +Public strSerialNumber As String ' Global variable for work order-serial number (collectively: Serial Number). +Public strDATETESTED As String ' Global variable for date tested. +' Global array for the Final Test test status read from the .DAT file (this includes the "PASS" or "FAIL" status, +' test results, and the number of decimal points to display). +Public strTestDATSTRING(1 To NUMTESTS) As String +' Global arrays for the Accuracy/Linearity test data read from the .DAT file. +Public strTSIM(1 To 5) As String ' Input value during acc/lin test (index is meas. #). +Public strOUTCALC(1 To 5) As String ' Calculated output value during acc/lin test (index is meas. #). +Public strOUTMEAS(1 To 5) As String ' Measured output value during acc/lin test (index is meas. #). +Public strERROROUT(1 To 5) As String ' Calculated output error during acc/lin test (index is meas. #). +Public strACCSTAT(1 To 5) As String ' PASS or FAILED status string during acc/lin test (index is meas. #). +' Global variable for data read from the datalog (.DAT) file. +Public sLOWV As Single ' Obsolete read value from datalog file. +Public sHIGHV As Single ' Obsolete read value from datalog file. +Public sTOTLRESPEC As Single ' Obsolete read value from datalog file. + + +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + + On Error GoTo ErrorHandler + + ' Initialize Final Test names and units for tests and stored + ' values for data read from datalog and database files. + + '------------------------------------------------------ + ' Display program screen. + ' NOTE: if screen is shown modal, it will NOT show up + ' in the taskbar nor be found by clicking alt-tab to + ' select open programs! + '------------------------------------------------------ + + 'frmDBselect.Show vbModal ' Show screen (modal). + frmDSfiles.Show ' Show screen (nonmodal). + + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + + MsgBox ("Error in ""Main"" subroutine = " & Err.Description) + +End Sub + +Public Function funcMakePathFromFolder(ByVal strSubfolderName As String) As Boolean + '------------------------------------------------------------------------------------- + ' Function to create directories (folders) as needed, based on the passed parameter. + ' + ' NOTE: The "strSubfolderName" parameter is assumed to be a complete path, including + ' drive letter. This subroutine does not handle other path forms, such as + ' those starting with a "\\" (as in "\\fileserver\") and will generate an + ' error message and return "False" if an invalid folder name is passed. + '------------------------------------------------------------------------------------- + Dim arTemp() As String ' Dynamic array to store parsed values from "Split" function. + Dim iArrayIndex As Long ' String-array index. + Dim strFolder As String ' (Re)combined folder name string, concatenated piece by piece from original. + Dim objFSO As New Scripting.FileSystemObject ' New instance of FileSystemObject. + + On Error GoTo ErrorHandler + + 'strFolder = sFolderRoot & "\" ' Initialize to root. + 'strFolder = Left$(strSubfolderName, 2) & "\" ' Initialize to drive letter and backslash. + strFolder = "" ' Initialize to drive letter and backslash. + + arTemp = Split(strSubfolderName, "\") ' Split "full" folder name to array of strings at each backslash. + + ' For each split string (folder name) check if folder already exists. Lower and upper bounds of array are determined + ' by the array itself (the number of strings depends on the contents of the "full" folder name (complete path). The + ' initial string should be the drive name. If the folder does not exist, it is created. The "combined" folder name is + ' then re-combined by adding a backslash and then the next string in the array (the next folder name). + For iArrayIndex = LBound(arTemp) To UBound(arTemp) + strFolder = strFolder & arTemp(iArrayIndex) & "\" + If Not objFSO.FolderExists(strFolder) Then + Call objFSO.CreateFolder(strFolder) + End If + Next iArrayIndex + Set objFSO = Nothing + + funcMakePathFromFolder = True ' Set function return before exit. + + Exit Function ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Set objFSO = Nothing + funcMakePathFromFolder = False ' Set function error return. + MsgBox ("Error in function ""funcMakePathFromFolder"" = " & Err.Description & vbCrLf & _ + "Folder name = " & strFolder & vbCrLf & _ + "Function returning ""False""!") +End Function + +Public Sub subInitTestNAMES() + ' This subroutine initializes the "strTestNAMES" global array with the + ' names of the tests for the text data file. + ' + Dim iIndex As Integer + + On Error GoTo ErrorHandler + + strTestNAMES(1) = "Supply Current" + strTestNAMES(2) = "Supply Curr. w/ EXC Load" + strTestNAMES(3) = "Exc. Current @ -f.s." + strTestNAMES(4) = "Exc. Current @ +f.s." + strTestNAMES(5) = "" + strTestNAMES(6) = "" + strTestNAMES(7) = "Excitation Voltage" + strTestNAMES(8) = "EXC.Load Regulation" + strTestNAMES(9) = "Output Reg. w/ EXC Load" + strTestNAMES(10) = "Excitation Current Limit" + strTestNAMES(11) = "Linearity" + strTestNAMES(12) = "Accuracy" + strTestNAMES(13) = "Lead Resistance Effect" + strTestNAMES(14) = "Power Supply Sensitivity" + strTestNAMES(15) = "Input Resistance" + strTestNAMES(16) = "Open Thermocouple Resp." + strTestNAMES(17) = "Frequency Response" + strTestNAMES(18) = "Step Response" + strTestNAMES(19) = "Output Noise" + strTestNAMES(20) = "Chg. in Iout w/ Max Load" + + Exit Sub ' Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subInitTestNAMES"" = " & Err.Description), vbCritical +End Sub + +Public Function funcIsMatchingString(ByVal strFirst As String, ByVal strSecond As String) As Boolean + ' This function returns "True" if the "trimmed" values of the two strings that are passed + ' to it match. + ' + On Error GoTo ErrorHandler + + If (Trim(strFirst) = Trim(strSecond)) Then + funcIsMatchingString = True ' Strings match. + Else + funcIsMatchingString = False ' Strings do not match. + End If + + Exit Function ' Exit before error handler. + +ErrorHandler: + funcIsMatchingString = False ' Error value. + MsgBox ("Error in ""funcIsMatchingString"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Public Sub subProcessDatasheetFiles(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim objFSO As FileSystemObject + Dim objFolder As Folder + Dim objFile As File + Dim NextRow As Long + Dim iCount As Integer + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject. + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get the folder. + Set objFolder = objFSO.GetFolder(strFolderName) + + 'If the folder does not contain files, exit the sub. + 'If (objFolder.Files.Count = 0) Then + ' MsgBox "No files were found...", vbExclamation + ' Exit Sub + 'End If + + iCount = 0 'Initialize. + + 'Loop through each file in the folder + For Each objFile In objFolder.Files + frmDSfiles.lstInvalidDS.AddItem objFile.Name + iCount = iCount + 1 + frmDSfiles.txtInvalidCount.Text = iCount + Next objFile + + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDatasheetFiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Public Sub subDirList(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim strFileName As String + Dim strDirSpec As String + Dim iCountInvalid As Integer + Dim iCountRename As Integer + + On Error GoTo ErrorHandler + + 'Initialize. + iCountInvalid = 0 + iCountRename = 0 + frmDSfiles.lstInvalidDS.Clear + + 'Set Dir$ function specification (directory path and search criteria). + strDirSpec = strFolderName & "\*.txt" + strFileName = Dir$(strDirSpec, vbNormal) + + 'If the folder does not contain files, exit the sub. + 'If (strFileName = "") Then + ' MsgBox "No files were found...", vbExclamation + ' Exit Sub + 'End If + + 'Loop through each file in the folder + Do While (strFileName <> "") + strFileName = Dir$ + If (strFileName <> "") Then + frmDSfiles.lstInvalidDS.AddItem strFileName + iCount = iCount + 1 + End If + Loop + frmDSfiles.txtInvalidCount.Text = iCountInvalid + frmDSfiles.txtRenameCount.Text = iCountRename + frmDSfiles.Refresh + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDirList"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcParseFileName(ByVal strFullFileName) As String + 'This function parses out the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned in + 'uppercase if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem, a null string is returned. + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + strSerial = UCase$(strFullFileName) 'Set serial number string to full file name in uppercase. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strSerial) 'Get length of the full file name. + strSerial = Left$(strSerial, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcParseFileName = strSerial + Else + funcParseFileName = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcParseFileName = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcParseFileName = "" 'Error value. + MsgBox ("Error in ""funcParseFileName"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcIsDashValid(ByVal strSerial) As String + 'This function checks for a valid dash ("-") in the passed (module) serial string. + 'For the dash to be valid, there must be a dash in the string, there must be only + 'one dash in the string, and the dash must be the second or third character from + 'the end (right side) of the string. The function returns "True" if there is a + 'valid (single, correctly located) dash, and "False" otherwise, including when + 'there is an error in the function. + ' + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strSerial) 'Length of serial string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strSerial, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strSerial, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the serial string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end. + funcIsDashValid = False 'Error value (invalid dash). + Else + funcIsDashValid = True 'Good value (valid dash). + End If + Else + 'More than one dash in the serial string. + funcIsDashValid = False 'Error value (invalid dash). + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsDashValid = False 'Error value (invalid dash). + MsgBox ("Error in ""funcIsDashValid"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcSNparse(ByVal strFullFileName As String, ByRef strWorkOrderNum As String, ByRef strDashNum As String) As Boolean + 'Function that receives the name of the datasheet sheet file and parses out both the work order number and + 'dash number from the complete module serial number contained in the file name, and returns them (by reference) + 'as the "strWorkOrderNum" and "strDashNum" parameters. The function returns "True" if there is no error and + 'work order and dash numbers could be successfully parsed, and "False" if there is any error or problem. + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iCharLoc As Integer 'Character location in file name string. + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + 'Get serial number (file name) string from full file name. + strSerial = funcParseFileName(strFullFileName) + + 'Validate serial number, and parse if valid. + If (strSerial <> "") Then + 'Valid serial number. Perform further serial number validation. + If (funcIsDashValid(strSerial) = True) Then + 'Serial number contains a single, valid dash. + + 'Get length of serial number + iSTRlength = Len(strSerial) + + 'Location of dash characters (from start (left) of string) when searched from the left. + iCharLoc = InStr(strSerial, "-") + + 'Parse work order# (characters to the left of the dash) from the serial number string. + strWorkOrderNum = Left$(strSerial, iCharLoc - 1) + + 'Parse the dash# (characters to the right of the dash) from the serial number string. + strDashNum = Mid$(strSerial, iCharLoc + 1, iSTRlength - iCharLoc%) + + Else + 'Invalid dash number (missing, duplicate, or in wrong location) in serial number. + funcSNparse = False ' Error value. + Exit Function 'Exit function on erroneous file name. + End If + Else + 'Not a valid datasheet file name. + funcSNparse = False ' Error value. + Exit Function 'Exit function on erroneous file name. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcSNparse = False ' Error value. + MsgBox ("Error in ""funcSNparse"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + + + + + + +#If 0 Then +Function ISPOSNUMBER%(TESTVALUE$) + 'Function that checks if the passed string is a positive number (entirely numerical) + 'or is a string (at least one non-numerical character). Returns "1" for a positive + ' number or "0" anything else + ISPOSNUMBER% = 1 'Initialize to function return for numerical string + N% = Len(TESTVALUE$) 'Get length of passed string + Do Until N% = 0 + TVC$ = Mid$(TESTVALUE$, N%, 1) 'Get nth character of passed string + CHARVALUE% = Asc(TVC$) 'Get decimal ASCII code for nth character + If ((CHARVALUE% < 48) Or (CHARVALUE% > 57)) Then + ISPOSNUMBER% = 0 'Character not ASCII code for 0 through 9 + End If + N% = N% - 1 + Loop + +End Function +#End If + + + + + + + + + +Private Function funcIsRenameDSname(ByVal strWorkOrder) As Boolean + ' This function returns "True" if the "trimmed" values of the two strings that are passed + ' to it match. + ' + On Error GoTo ErrorHandler + + If (Trim(strFirst) = Trim(strSecond)) Then + funcIsInvalidDSname = True ' Strings match. + Else + funcIsInvalidDSname = False ' Strings do not match. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsMatchingString = False ' Error value. + MsgBox ("Error in ""funcIsInvalidDSname"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + + + + + + + + + + +Private Function funcIsInvalidDSname(ByVal strFileName) As Boolean + ' This function returns "True" if the "trimmed" values of the two strings that are passed + ' to it match. + ' + On Error GoTo ErrorHandler + + If (Trim(strFirst) = Trim(strSecond)) Then + funcIsInvalidDSname = True ' Strings match. + Else + funcIsInvalidDSname = False ' Strings do not match. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsMatchingString = False ' Error value. + MsgBox ("Error in ""funcIsInvalidDSname"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + + + + + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.vbp new file mode 100644 index 0000000..6e341df --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\..\..\Windows\SysWOW64\msstdfmt.dll#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; TABCTL32.OCX +Module=A_Main; DFWDS.bas +Form=frmDSfiles.frm +Startup="Sub Main" +HelpFile="" +Title="PrintDSCAmost" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.vbw new file mode 100644 index 0000000..6b81a4f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/frmDSfiles.frm b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/frmDSfiles.frm new file mode 100644 index 0000000..c50dbc2 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/frmDSfiles.frm @@ -0,0 +1,291 @@ +VERSION 5.00 +Begin VB.Form frmDSfiles + BorderStyle = 1 'Fixed Single + Caption = "Datasheet Files" + ClientHeight = 9555 + ClientLeft = 45 + ClientTop = 375 + ClientWidth = 8535 + Icon = "frmDSfiles.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form1" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 9555 + ScaleWidth = 8535 + StartUpPosition = 1 'CenterOwner + Begin VB.ListBox lstInvalidDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":030A + Left = 3600 + List = "frmDSfiles.frx":0311 + Sorted = -1 'True + TabIndex = 13 + Top = 1560 + Width = 2295 + End + Begin VB.ListBox lstRenameDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":0323 + Left = 6120 + List = "frmDSfiles.frx":032A + Sorted = -1 'True + TabIndex = 12 + Top = 1560 + Width = 2295 + End + Begin VB.TextBox txtRenameCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 7200 + TabIndex = 10 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.TextBox txtInvalidCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 4680 + TabIndex = 6 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.DriveListBox vlbDriveSelect + Height = 315 + Left = 120 + TabIndex = 5 + Top = 1320 + Width = 3255 + End + Begin VB.DirListBox dlbFolderSelect + Height = 3015 + Left = 120 + TabIndex = 4 + Top = 1680 + Width = 3255 + End + Begin VB.CommandButton btnProcess + Caption = "Process" + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 1 + ToolTipText = "Click to print text datasheets from data in stored-data file." + Top = 4920 + Width = 2055 + End + Begin VB.CommandButton btnExit + Cancel = -1 'True + Caption = "Exit Datasheet Program " + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 0 + ToolTipText = "Click to exit the program." + Top = 6240 + Width = 2055 + End + Begin VB.Label lblRenameCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 11 + Top = 9120 + Width = 975 + End + Begin VB.Label lblRenameDS + Alignment = 2 'Center + Caption = "Files to Rename" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 9 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidDS + Alignment = 2 'Center + Caption = "Invalid DS Names" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 8 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 7 + Top = 9120 + Width = 975 + End + Begin VB.Label lblMain + Alignment = 2 'Center + Caption = "Select Folder to List Datasheet Files with Invalid Names or That Need to be Renamed for the Website" + BeginProperty Font + Name = "Arial" + Size = 15.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 735 + Left = 120 + TabIndex = 3 + Top = 120 + Width = 8295 + End + Begin VB.Label lblFileSelect + Alignment = 2 'Center + Caption = "Select Datasheet Folder" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 120 + TabIndex = 2 + Top = 960 + Width = 3255 + End +End +Attribute VB_Name = "frmDSfiles" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + 'Put operations to run when the form loads here. + Me.lstInvalidDS.Clear + Me.lstRenameDS.Clear +End Sub + +Private Sub Form_Unload(Cancel As Integer) + 'The form is unloaded here, since the "Cancel" parameter is unmodified by the unload event. + End 'Exit program. +End Sub + +Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) + If (KeyCode = vbKeyF10) Then + Unload Me 'Call form unload event (and run unload code). + End If +End Sub + +Private Sub dlbFolderSelect_Change() + 'flbFileSelect.Path = dlbFolderSelect.Path + 'Call subProcessDatasheetFiles(dlbFolderSelect.Path) + Call subDirList(dlbFolderSelect.Path) + 'Me.txtInvalidCount.Text = Me.lstInvalidDS.ListCount + 'Me.txtInvalidCount.Text = Me.lstRenameDS.ListCount +End Sub + +Private Sub vlbDriveSelect_Change() + ' The Drive property also returns the volume label, so trim it. + dlbFolderSelect.Path = Left$(vlbDriveSelect.Drive, 1) & ":\" +End Sub + +Private Sub btnExit_Click() + Unload Me +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/frmDSfiles.frx b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/frmDSfiles.frx new file mode 100644 index 0000000..91de641 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-24/frmDSfiles.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.bas new file mode 100644 index 0000000..8e22665 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.bas @@ -0,0 +1,659 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2014_09_26" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/24 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = this file, main code module. +' VB FORMS: frmDBselect.frm = form to select directory and .DAT file for model database. +' frmDATAselect.frm = form to select .DAT file for stored model datasheet data and print +' text file datasheets. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/24 PWR Initial version. +' +' ------------------------------------------------------------------------------------------------------------------------------------- + +'---------------------------------------------------------------------------------------------------- +' Hard-coded values. +'---------------------------------------------------------------------------------------------------- +Public Const PRINTSHEET_SUBDIR = "PRINT" ' Hardcoded printed datasheet directory (below folder with .DAT files). +Public Const NUMPTS = 5 ' Hardcoded number of points for accuracy/linearity measurements. +Public Const NUMTESTS = 20 ' Hardcoded maximum array index (# of stored tests) for STATUS (strTestDATSTRING) and other arrays. + +' Global variables. +Public strDBFILEname As String ' Global variable to hold database (.DAT) file name. +Public strDBFILEfolder As String ' Global variable to hold database (.DAT) file folder. +Public strDATFILEname As String ' Global variable to hold stored datasheet data (.DAT) file name. +Public strDATFILEfolder As String ' Global variable to hold stored datasheet data (.DAT) file folder. +Public iFileCount As Integer ' Count of number of text datasheet files "printed". +Public iDupCount As Integer ' Count of number of text datasheet files "printed" over an existing file. +Public bDisplayMessages As Boolean ' Flag, "True" to display error messages in various functions and subroutines. +Public bPrintFailingUnits As Boolean ' Flag, "True" to also print text log files from failing units. + +' Global arrays. +Public strTestNAMES(1 To NUMTESTS) As String ' Global array for the Final Test test names. +Public strTestUNITS(1 To NUMTESTS) As String ' Global array for the Final Test test units. +Public strTSPEC(1 To NUMTESTS) As String ' Global array for the Final Test test limits strings for printed datasheet. +Public strMODNAME As String ' Global variable for module model name: "SCM5B30-1419", for example. +Public strSerialNumber As String ' Global variable for work order-serial number (collectively: Serial Number). +Public strDATETESTED As String ' Global variable for date tested. +' Global array for the Final Test test status read from the .DAT file (this includes the "PASS" or "FAIL" status, +' test results, and the number of decimal points to display). +Public strTestDATSTRING(1 To NUMTESTS) As String +' Global arrays for the Accuracy/Linearity test data read from the .DAT file. +Public strTSIM(1 To 5) As String ' Input value during acc/lin test (index is meas. #). +Public strOUTCALC(1 To 5) As String ' Calculated output value during acc/lin test (index is meas. #). +Public strOUTMEAS(1 To 5) As String ' Measured output value during acc/lin test (index is meas. #). +Public strERROROUT(1 To 5) As String ' Calculated output error during acc/lin test (index is meas. #). +Public strACCSTAT(1 To 5) As String ' PASS or FAILED status string during acc/lin test (index is meas. #). +' Global variable for data read from the datalog (.DAT) file. +Public sLOWV As Single ' Obsolete read value from datalog file. +Public sHIGHV As Single ' Obsolete read value from datalog file. +Public sTOTLRESPEC As Single ' Obsolete read value from datalog file. + + +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + + On Error GoTo ErrorHandler + + ' Initialize Final Test names and units for tests and stored + ' values for data read from datalog and database files. + + '------------------------------------------------------ + ' Display program screen. + ' NOTE: if screen is shown modal, it will NOT show up + ' in the taskbar nor be found by clicking alt-tab to + ' select open programs! + '------------------------------------------------------ + + 'frmDBselect.Show vbModal ' Show screen (modal). + frmDSfiles.Show ' Show screen (nonmodal). + + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + + MsgBox ("Error in ""Main"" subroutine = " & Err.Description) + +End Sub + +Public Function funcMakePathFromFolder(ByVal strSubfolderName As String) As Boolean + '------------------------------------------------------------------------------------- + ' Function to create directories (folders) as needed, based on the passed parameter. + ' + ' NOTE: The "strSubfolderName" parameter is assumed to be a complete path, including + ' drive letter. This subroutine does not handle other path forms, such as + ' those starting with a "\\" (as in "\\fileserver\") and will generate an + ' error message and return "False" if an invalid folder name is passed. + '------------------------------------------------------------------------------------- + Dim arTemp() As String ' Dynamic array to store parsed values from "Split" function. + Dim iArrayIndex As Long ' String-array index. + Dim strFolder As String ' (Re)combined folder name string, concatenated piece by piece from original. + Dim objFSO As New Scripting.FileSystemObject ' New instance of FileSystemObject. + + On Error GoTo ErrorHandler + + 'strFolder = sFolderRoot & "\" ' Initialize to root. + 'strFolder = Left$(strSubfolderName, 2) & "\" ' Initialize to drive letter and backslash. + strFolder = "" ' Initialize to drive letter and backslash. + + arTemp = Split(strSubfolderName, "\") ' Split "full" folder name to array of strings at each backslash. + + ' For each split string (folder name) check if folder already exists. Lower and upper bounds of array are determined + ' by the array itself (the number of strings depends on the contents of the "full" folder name (complete path). The + ' initial string should be the drive name. If the folder does not exist, it is created. The "combined" folder name is + ' then re-combined by adding a backslash and then the next string in the array (the next folder name). + For iArrayIndex = LBound(arTemp) To UBound(arTemp) + strFolder = strFolder & arTemp(iArrayIndex) & "\" + If Not objFSO.FolderExists(strFolder) Then + Call objFSO.CreateFolder(strFolder) + End If + Next iArrayIndex + Set objFSO = Nothing + + funcMakePathFromFolder = True ' Set function return before exit. + + Exit Function ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Set objFSO = Nothing + funcMakePathFromFolder = False ' Set function error return. + MsgBox ("Error in function ""funcMakePathFromFolder"" = " & Err.Description & vbCrLf & _ + "Folder name = " & strFolder & vbCrLf & _ + "Function returning ""False""!") +End Function + +Public Sub subDirListFSO(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim objFSO As FileSystemObject + Dim objFolder As Folder + Dim objFile As File + Dim NextRow As Long + Dim iCount As Integer + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject. + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get the folder. + Set objFolder = objFSO.GetFolder(strFolderName) + + 'If the folder does not contain files, exit the sub. + 'If (objFolder.Files.Count = 0) Then + ' MsgBox "No files were found...", vbExclamation + ' Exit Sub + 'End If + + iCount = 0 'Initialize. + + 'Loop through each file in the folder + For Each objFile In objFolder.Files + frmDSfiles.lstInvalidDS.AddItem objFile.Name + iCount = iCount + 1 + frmDSfiles.txtInvalidCount.Text = iCount + Next objFile + + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDirListFSO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Public Sub subDirList(ByVal strFolderName As String) + ' + ' + 'Declare the variables. + Dim strFileName As String + Dim strDirSpec As String + Dim lCountInvalid As Long + Dim lCountRename As Long + Dim lCountAll As Long + Dim strMoveLoc As String + Dim strLogFileNameLoc As String + Dim strDatasheetLoc As String + + On Error GoTo ErrorHandler + + + 'Initialize file names and locations. + 'This is TEMPORARY, since they should + 'eventually be read from a file. + strMoveLoc = "C:\_CODE\DFWDS\Bad_Datasheets" + strLogFileNameLoc = "C:\_CODE\DFWDS\Log\DFWDS.log" + strDatasheetLoc = "C:\_CODE\DFWDS\WebDatasheets" + + 'Initialize. + lCountInvalid = 0 + lCountRename = 0 + lCountAll = 0 + frmDSfiles.lstInvalidDS.Clear + frmDSfiles.lstRenameDS.Clear + + 'Set Dir$ function specification (directory path and search criteria). + 'strDirSpec = strFolderName & "\*.txt" + strDirSpec = strFolderName & "\*.*" + strFileName = Dir$(strDirSpec, vbNormal) + + 'Loop through each file in the folder + Do While (strFileName <> "") + strFileName = Dir$ + If (strFileName <> "") Then + Call subProcessDSfile(strFileName, strMoveLoc, strLogFileNameLoc, lCountRename, lCountInvalid) + lCountAll = lCountAll + 1 'Increment total count. + End If + Loop + + 'Set count displays. + frmDSfiles.txtInvalidCount.Text = lCountInvalid + frmDSfiles.txtRenameCount.Text = lCountRename + frmDSfiles.txtAllCount.Text = lCountAll + frmDSfiles.Refresh + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDirList"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subProcessDSfile(ByVal strDSfileName As String, ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, _ + ByRef lCountRename As Long, ByRef lCountInvalid As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the passed file name. If it is determined to be an invalid name for the Dataforth + 'website, the file is moved to the passed directory location and this action is recorded in a log file + 'whose name and location is also passed as a parameter. If the file name matches the format of "encoded" + 'datasheet file names from the DOS test programs, the file is renamed to the appropriate "unencoded" + 'datasheet file name and this action is also recorded to the specified log file. The subroutine posts + 'error messages for problems that may be encountered during file processing. + ' + ' Inputs: + ' strDSfileName: Datasheet file name. + ' strDSmoveLocation: Directory location that invalid files are copied. Invalid files include non-text + ' files and files with names that do not match the format for the Dataforth website. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' lCountInvalid: Passes count of invalid datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + ' lCountRename: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalid: Passes count of invalid datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + ' lCountRename: Passes count of renamed datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strWorkOrderNum As String 'Work order number. + Dim strFullFileName As String 'Full file name (including extension). + Dim strFileNameOnly As String 'File name (only). + Dim iDashLoc As Integer 'Dash location in file name (only) string. + Dim iFNOlength As Integer 'Length of file name (only) string. + Dim strWOdecoded As String 'Work order number. + + On Error GoTo ErrorHandler + + 'Get uppercase-only version of the full file name. + 'This is necessary for later processing of the + 'datasheet files (including determining whether + 'they are validly-named datasheet files). + strFullFileName = UCase$(strDSfileName) + + 'Get the file name (only). This should be the (encoded + 'or unencoded) module serial number. Note that the + 'function requires a full file name already in + 'all-UPPERCASE. + strFileNameOnly = funcGetFileNameOnly(strFullFileName) + + 'Check for text file. + If (strFileNameOnly = "") Then + 'Not a text file (null return from funcGetFileNameOnly). + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-text file. + End If + + 'Check for valid dash location (and/or existence) and a valid dash number. + iDashLoc = funcGetDashLoc(strFileNameOnly) 'Get dash location. + + 'Check for valid location. + If Not (funcGetDashLoc(strFileNameOnly) > 0) Then + 'Dash (or dash number) is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + + 'Parse work order# (characters to the left of + 'the dash) from the serial number string. + strWorkOrderNum = Left$(strFileNameOnly, iDashLoc - 1) + + If (funcIsAllNumbers(strWorkOrderNum) = True) Then + 'Work order number string is all numbers, + 'check for leading "0". + If (Left$(strWorkOrderNum, 1) = "0") Then + 'Leading "0" in all-numeric work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + Else + 'Work order string is not all numbers. Check if + 'it is matches the format of a DOS-encoded work + 'order number. + If (funcISrenameWO(strWorkOrderNum) = True) Then + 'DOS-encoded work order number. Rename file + 'to unencoded datasheet file name. + Call subDSrename(strFullFileName, strDSlogNameLoc, lCountRename) + Else + 'Not a DOS-encoded work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmove(strFullFileName, strDSmoveLocation, strDSlogNameLoc, lCountInvalid) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + End If + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcGetFileNameOnly(ByVal strFullFileName As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned + 'if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem (such as a blank file name passed to the function), a null string + 'is returned. + ' + 'NOTE: The passed full file name must be in all-UPPERCASE for the ".TXT" check to work. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strFullFileName) 'Get length of the full file name. + strSerial = Left$(strFullFileName, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcGetFileNameOnly = strSerial + Else + funcGetFileNameOnly = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcGetFileNameOnly = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcGetFileNameOnly = "" 'Error value. + MsgBox ("Error in ""funcGetFileNameOnly"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Function funcIsAllNumbers(ByVal strTestString As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'Function that checks whether the passed string consists of only numerical characters. The function + 'returns "True" if each character in the string is a number, and "False" if any character is not + 'a number or if there is some other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strChar As String + Dim iDx As Integer + + On Error GoTo ErrorHandler + + 'Initialize to "all numbers" value. + funcIsAllNumbers = True + + For iDx = 1 To Len(strTestString) 'Loop from 1st character to last character of string. + 'See if the next character is a non-number. + strChar = Mid$(strTestString, iDx, 1) 'Get next character. + If ((strChar < "0") Or (strChar > "9")) Then 'Character is not "0" through "9". + funcIsAllNumbers = False 'Set "not all numbers" value. + Exit For 'Exit the loop (no need to continue after first non-number). + End If + Next iDx + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsAllNumbers = False 'Error ("not all numbers") value. + MsgBox ("Error in ""funcIsAllNumbers"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetDashLoc(ByVal strFileNameOnly As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the dash ("-") location in the passed file name (only) string. It returns + 'an error value of "0" if no dash is found, or more than one dash is found, if there are more + 'than one characters after the dash, and if any of the characters after the dash are not a + 'number, or if there are any other problems in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + Dim strDashNum As String 'Dash number string. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strFileNameOnly) 'Length of file name (only) string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strFileNameOnly, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strFileNameOnly, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end (dash number + 'more than two characters, or less than one). + funcGetDashLoc = 0 'Error value (invalid dash). + Else + 'Dash number is one or two characters. Get for an all-number dash number. + strDashNum = Mid$(strFileNameOnly, iDashLocL + 1, iSTRlength - iDashLocL) + If (funcIsAllNumbers(strDashNum) = True) Then + 'Dash number is all numbers. + funcGetDashLoc = iDashLocL 'Good value (valid dash). + Else + 'Dash number is not valid (not all numbers). + funcGetDashLoc = 0 'Error value (invalid dash). + End If + End If + Else + 'More than one dash in the serial string. + funcGetDashLoc = 0 'Error value (invalid dash). + End If + + Exit Function 'Exit before error handler. +ErrorHandler: + funcGetDashLoc = 0 'Error (not valid) value. + MsgBox ("Error in ""funcIsValidDash"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDecodeWOchar(ByVal strWOnum As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns a two-character string decoded from the first character of the + 'passed work order number string. If the first character is "A" through "J", the + 'function returns "10" through "19", respectively, which represents the values that + 'are encoded in valid DOS-encoded datasheet file names. If the first character is + 'not "A" or "J" or a letter in between, or if there is some problem in the function, + 'the function returns a null string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strFirstChar As String 'First character in passed work order number string. + + On Error GoTo ErrorHandler + + If (strWOnum = "") Then + 'Null string, return error value (null string). + funcDecodeWOchar = "" 'Error value. + Else + 'String has at least one character, check for "A" through "J". + strFirstChar = Left$(strWOnum, 1) 'Get first character of passed work order number. + Select Case strFirstChar + Case strFirstChar = "A" + funcDecodeWOchar = "10" 'Decode of first character. + Case strFirstChar = "B" + funcDecodeWOchar = "11" 'Decode of first character. + Case strFirstChar = "C" + funcDecodeWOchar = "12" 'Decode of first character. + Case strFirstChar = "D" + funcDecodeWOchar = "13" 'Decode of first character. + Case strFirstChar = "E" + funcDecodeWOchar = "14" 'Decode of first character. + Case strFirstChar = "F" + funcDecodeWOchar = "15" 'Decode of first character. + Case strFirstChar = "G" + funcDecodeWOchar = "16" 'Decode of first character. + Case strFirstChar = "H" + funcDecodeWOchar = "17" 'Decode of first character. + Case strFirstChar = "I" + funcDecodeWOchar = "18" 'Decode of first character. + Case strFirstChar = "J" + funcDecodeWOchar = "19" 'Decode of first character. + Case Else + 'Not "A" through "J" + funcDecodeWOchar = "" 'Error value. + End Select + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcDecodeWOchar = "" 'Error value. + MsgBox ("Error in ""funcDecodeWOchar"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcISrenameWO(ByVal strWOnumber) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed work order number matches the format of a DOS-encoded + 'work order number (for work orders above the value of "99,999"). A DOS-encoded work order number + 'will be five characters long, start with "A" through "J", and have all numbers for the remaining + 'characters. The function will return "False" if any of these conditions are not true, or there is + 'any other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLastFour As String + Dim strFirstOne As String + + On Error GoTo ErrorHandler + + If (Len(strWOnumber) <> 5) Then + 'Not five characters long. + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strFirstOne = UCase$(Left$(strWOnumber, 1)) + If ((strFirstOne < "A") Or (strFirstOne > "J")) Then + 'First character not "A" through "J". + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strLastFour = Right$(strWOnumber, 4) + If (funcIsAllNumbers(strLastFour) = True) Then + funcISrenameWO = True 'Set "valid rename string" value. + Else + 'Last four characters not all numberss. + funcISrenameWO = False 'Set "not a valid rename string" value. + End If + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcISrenameWO = False 'Error value (not valid "rename" string). + MsgBox ("Error in ""funcISrenameWO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subDSmove(ByVal strFullFileName As String, ByVal strDSmoveLocation As String, _ + ByVal strDSlogNameLoc As String, ByRef lCountInvalid As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to move the file specified by the passed file name to the directory specified by the passed "move" + 'directory. This action is recorded in a log file whose name and location is also passed as a parameter. + 'The subroutine increments a by-reference count parameter for each file moved, which can be used for a + 'status display, such as "total invalid files", or some similar use. Errors encountered during the subroutine + 'will be logged in specified log file and error messages will be displayed. + ' + ' Inputs: + ' strFullFileName: Full file name of the file to be moved (includes file extension). + ' strDSmoveLocation: Directory location where the file is moved. + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' lCountInvalid: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalid: Passes count of invalid datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + + On Error GoTo ErrorHandler + + +'NOTE: The code below is temporary code for debug. The "move" code is not yet in the subroutine!!! + frmDSfiles.lstInvalidDS.AddItem strFullFileName 'Add file to be moved (invalid DS file name) to the list. + lCountInvalid = lCountInvalid + 1 'Increment count. + + + + Exit Sub ' Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDSmove"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subDSrename(ByVal strFullFileName As String, ByVal strDSlogNameLoc As String, ByRef lCountRename As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to rename the DOS-encoded datasheet file specified by the passed full file name and to recorded + 'this action in a log file whose name and location is also passed as a parameter. This subroutine is run + 'after a datasheet file with a DOS-encoded name is found (this is a valid datasheet file name with five + 'characters for the work order number, the first character "A" through "J", and all of the remaining work + 'order number characters are a number). The "A" through "J" first character is renamed to the appropriate + 'two-number "decoded" value ("10" through "19"), while the remaining characters in the file name portion of + 'the full datasheet file name remain unchanged. The subroutine increments a by-reference count parameter for + 'each file renamed, which can be used for a "total files renamed" status display, or some similar use. Errors + 'encountered during the subroutine will be logged in specified log file and error messages will be displayed. + ' + ' Inputs: + ' strFullFileName: Full file name of the file to be moved (includes file extension). + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' lCountRename: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountRename: Passes count of renamed datasheet files back to the calling routine + ' by reference for status displays, etc. Also used, on first call, + ' to pass the initial count from the calling routine (see entry in + ' "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + + On Error GoTo ErrorHandler + + +'NOTE: The code below is temporary code for debug. The "rename" code is not yet in the subroutine!!! + frmDSfiles.lstRenameDS.AddItem strFullFileName 'Add file to be renamed to the list. + lCountRename = lCountRename + 1 'Increment count. + + + Exit Sub ' Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subDSrename"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.vbp new file mode 100644 index 0000000..086ed38 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\..\Windows\SysWOW64\msstdfmt.dll#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; TABCTL32.OCX +Module=A_Main; DFWDS.bas +Form=frmDSfiles.frm +Startup="Sub Main" +HelpFile="" +Title="PrintDSCAmost" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.vbw new file mode 100644 index 0000000..6b81a4f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/frmDSfiles.frm b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/frmDSfiles.frm new file mode 100644 index 0000000..5633535 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/frmDSfiles.frm @@ -0,0 +1,352 @@ +VERSION 5.00 +Begin VB.Form frmDSfiles + BorderStyle = 1 'Fixed Single + Caption = "Datasheet Files" + ClientHeight = 9555 + ClientLeft = 45 + ClientTop = 375 + ClientWidth = 8535 + Icon = "frmDSfiles.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form1" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 9555 + ScaleWidth = 8535 + StartUpPosition = 1 'CenterOwner + Begin VB.TextBox txtAllCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 1560 + TabIndex = 14 + Text = "0" + Top = 8040 + Width = 1215 + End + Begin VB.ListBox lstInvalidDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":030A + Left = 3600 + List = "frmDSfiles.frx":0311 + Sorted = -1 'True + TabIndex = 13 + Top = 1560 + Width = 2295 + End + Begin VB.ListBox lstRenameDS + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 7260 + ItemData = "frmDSfiles.frx":0323 + Left = 6120 + List = "frmDSfiles.frx":032A + Sorted = -1 'True + TabIndex = 12 + Top = 1560 + Width = 2295 + End + Begin VB.TextBox txtRenameCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 7200 + TabIndex = 10 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.TextBox txtInvalidCount + Alignment = 2 'Center + BeginProperty Font + Name = "MS Sans Serif" + Size = 13.5 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 495 + Left = 4680 + TabIndex = 6 + Text = "0" + Top = 9000 + Width = 1215 + End + Begin VB.DriveListBox vlbDriveSelect + Height = 315 + Left = 120 + TabIndex = 5 + Top = 1320 + Width = 3255 + End + Begin VB.DirListBox dlbFolderSelect + Height = 3015 + Left = 120 + TabIndex = 4 + Top = 1680 + Width = 3255 + End + Begin VB.CommandButton btnProcess + Caption = "Process" + BeginProperty Font + Name = "MS Sans Serif" + Size = 9.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 1 + ToolTipText = "Click to print text datasheets from data in stored-data file." + Top = 4920 + Width = 2055 + End + Begin VB.CommandButton btnExit + Cancel = -1 'True + Caption = "Exit Datasheet Program " + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 975 + Left = 720 + TabIndex = 0 + ToolTipText = "Click to exit the program." + Top = 6240 + Width = 2055 + End + Begin VB.Label lblAllFiles + Alignment = 2 'Center + Caption = "All Files" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 720 + TabIndex = 16 + Top = 7680 + Width = 2295 + End + Begin VB.Label lblAllCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 480 + TabIndex = 15 + Top = 8160 + Width = 975 + End + Begin VB.Label lblRenameCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 11 + Top = 9120 + Width = 975 + End + Begin VB.Label lblRenameDS + Alignment = 2 'Center + Caption = "Files to Rename" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 6120 + TabIndex = 9 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidDS + Alignment = 2 'Center + Caption = "Invalid DS Names" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 8 + Top = 1200 + Width = 2295 + End + Begin VB.Label lblInvalidCount + Alignment = 1 'Right Justify + Caption = "Count" + BeginProperty Font + Name = "MS Sans Serif" + Size = 8.25 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3600 + TabIndex = 7 + Top = 9120 + Width = 975 + End + Begin VB.Label lblMain + Alignment = 2 'Center + Caption = "Select Folder to List Datasheet Files with Invalid Names or That Need to be Renamed for the Website" + BeginProperty Font + Name = "Arial" + Size = 15.75 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 735 + Left = 120 + TabIndex = 3 + Top = 120 + Width = 8295 + End + Begin VB.Label lblFileSelect + Alignment = 2 'Center + Caption = "Select Datasheet Folder" + BeginProperty Font + Name = "MS Sans Serif" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 120 + TabIndex = 2 + Top = 960 + Width = 3255 + End +End +Attribute VB_Name = "frmDSfiles" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + 'Put operations to run when the form loads here. + Me.lstInvalidDS.Clear + Me.lstRenameDS.Clear + Me.txtAllCount.Text = "" + Me.txtInvalidCount.Text = "" + Me.txtRenameCount = "" +End Sub + +Private Sub Form_Unload(Cancel As Integer) + 'The form is unloaded here, since the "Cancel" parameter is unmodified by the unload event. + End 'Exit program. +End Sub + +Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) + If (KeyCode = vbKeyF10) Then + Unload Me 'Call form unload event (and run unload code). + End If +End Sub + +Private Sub dlbFolderSelect_Change() + 'flbFileSelect.Path = dlbFolderSelect.Path + 'Call subDirListFSO(dlbFolderSelect.Path) + 'Call subDirList(dlbFolderSelect.Path) + 'Me.txtInvalidCount.Text = Me.lstInvalidDS.ListCount + 'Me.txtInvalidCount.Text = Me.lstRenameDS.ListCount +End Sub + +Private Sub btnProcess_Click() + Call subDirList(dlbFolderSelect.Path) +End Sub + +Private Sub vlbDriveSelect_Change() + ' The Drive property also returns the volume label, so trim it. + dlbFolderSelect.Path = Left$(vlbDriveSelect.Drive, 1) & ":\" +End Sub + +Private Sub btnExit_Click() + Unload Me +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/frmDSfiles.frx b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/frmDSfiles.frx new file mode 100644 index 0000000..91de641 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-09-26/frmDSfiles.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.bas b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.bas new file mode 100644 index 0000000..9495829 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.bas @@ -0,0 +1,1048 @@ +Attribute VB_Name = "A_Main" +Option Explicit +' ------------------------------------------------------------------------------------------------------------------------------------- +' Software for filtering or renaming certain datasheet files for the Dataforth website. "Encoded" datasheet file names of a certain +' format are renamed, while datasheet file names that are invalid for the website are "filtered" by moving them out of the directory +' that is used for datasheets for the website. An external file is used to store the directory names of the main datasheet directory +' and the "filtered" datasheet files directory. The "filtered" files are moved to the "filtered" directory, rather than simply +' deleted, since they are sometimes used for test system debug or qualification. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' The following constant sets the name of the program version that it printed out in the data (CSV file) test report file. +Public Const PROGRAM_NAME = "DFWDS" +Public Const PROGRAM_DESCRIP = "Dataforth Website Datasheet Program" +Public Const PROGRAM_VERSION = "DFWDS_2014_09_29" + +' ------------------------------------------------------------------------------------------------------------------------------------- +' AUTHORS: Paul Reese +' DATE: 2014/09/29 +' EXECUTABLE: DFWDS.exe = Executable program file. +' CODE PROJECT: DFWDS.vbp = Visual Basic project file. +' CODE MODULES: DFWDS.bas = This file, the main code module. +' VB FORMS: frmSplash.frm = Program "splash" form displayed while the program is running. +' ------------------------------------------------------------------------------------------------------------------------------------- +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' REVISION RECORD +' +' DATE APPR DESCRIPTION +' ---- ---- ----------- +' 2014/09/29 PWR Initial version. +' +' ------------------------------------------------------------------------------------------------------------------------------------- +' +'Hard-coded "names" file name and location. +Public Const NAMES_FILE_NAME = "DFWDS_NAMES.txt" +Public Const NAMES_FILE_LOC = "C:\DFWDS" + +'Constants used as aliases for code readability. +Public Const DISPLAY_MESSAGES = "True" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const HIDE_MESSAGES = "False" 'Used, for example, by funcFolderExists to control display of error messages within the routine. +Public Const MOVE_FILE = "True" 'Used, for example, by subDSmoveRename to control whether the file is moved or renamed. +Public Const RENAME_FILE = "False" 'Used, for example, by subDSmoveRename to control whether the file is moved or renamed. +' +'================================================================================================================================ +Sub Main() + ' This is the startup (Main) subroutine for the program. Everything starts here. + ' + 'Define the local variables. + Dim strDSfolderName As String 'Datasheet file folder. + Dim strMoveLoc As String 'Invalid files are moved to this location. + Dim strLogFileName As String 'Log file name (only). + Dim strLogFileLoc As String 'Log file folder (only). + Dim strLogFileNameLoc As String 'Log file name and location. + Dim strLogFileLine As String 'Line for the log file. + Dim lCountRenameTotal As Long 'Number of datasheet files to be renamed. + Dim lCountInvalidTotal As Long 'Number of invalid datasheet files to be moved. + Dim lCountRenameGood As Long 'Number of datasheet files renamed. + Dim lCountInvalidGood As Long 'Number of invalid datasheet files. + Dim lCountAll As Long 'Total number of files in datasheet file directory. + Dim iLogFileHandle As Integer 'Log file number ("file handle"). + Dim dStartTime As Double 'Program start time. + Dim dEndTime As Double 'Program start time. + Dim strStartDate As String 'Date that the program is run. + Dim iOldMouse As Integer 'Store previous mouse state. + + On Error GoTo ErrorHandler + + 'Display program (splash) form. + frmSplash.Show + frmSplash.Refresh + + 'Get next valid file number (file + 'handle) for the log file. + iLogFileHandle = FreeFile + + 'Set start time. + dStartTime = Timer + + 'Initialize counts. + lCountRenameTotal = 0 + lCountInvalidTotal = 0 + lCountRenameGood = 0 + lCountInvalidGood = 0 + lCountAll = 0 + + 'Check for "names" file and read values from the file. End the + 'program if there is a problem with the "names" file. + If Not (functionNamesFileReadOK(strDSfolderName, strLogFileName, strLogFileLoc, strMoveLoc) = True) Then + End 'End the program. + End If + + 'Get starting date of program (for log file name and header) + 'and set full log file name based on the formatted date. + strStartDate = Format(Date$, "yyyy_mm_dd") 'Get starting date of program. + strLogFileName = strLogFileName & "_" & strStartDate & ".log" 'Get log file name with date. + + 'Open log file. + If (funcOpenLogFile(strLogFileName, strLogFileLoc, iLogFileHandle) = False) Then + Close #iLogFileHandle 'Close the log file. + Call subFileOpenMessage(strLogFileNameLoc) 'Display error message. + End 'Exit the program. + End If + + 'Write log file header. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Date: " & strStartDate & ", Time: " & Time$ + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "********************************************************************************" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + 'Call routine to process files in datasheet folder. + Call subProcessDSfolder(strDSfolderName, strMoveLoc, strLogFileNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood, lCountAll) + + 'Write log file footer information and close the log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total files processed = " & lCountAll + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Files to be renamed = " & lCountRenameTotal & vbCrLf & _ + "Files successfully renamed = " & lCountRenameGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Files to be moved = " & lCountInvalidTotal & vbCrLf & _ + "Files successfully moved = " & lCountInvalidGood + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "Total files to be changed = " & (lCountInvalidTotal + lCountRenameTotal) & vbCrLf & _ + "Total files successfully changed = " & (lCountInvalidGood + lCountRenameGood) + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + dEndTime = Timer 'Set end time. + strLogFileLine = "Elapsed time = " & Format(dEndTime - dStartTime, "##0.0") & " seconds" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + strLogFileLine = "--------------------------------------------------------------------------------" + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + Close #iLogFileHandle + + 'Unload the program (splash) form. + Unload frmSplash 'Unload the network-copy program splash screen. + + End 'Exit program. + + Exit Sub ' Exit subroutine (before the error handler) if no error. +ErrorHandler: + Close #iLogFileHandle + MsgBox ("Error in ""Main"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End 'Exit program. +End Sub + +Public Function functionNamesFileReadOK(ByRef strDSfolderName As String, ByRef strLogFileName As String, _ + ByRef strLogFileLoc As String, ByRef strMoveLoc As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function checks for the presence of the "names" file holding the locations of the datasheet + 'file folder, the invalid file "move" folder, and the log file folder for the program as well as + 'the log file name. If the "names" file is found, this function reads lines from the file and puts + 'the values obtained in the appropriate variables that are returned, by reference, for use in other + 'routines. The validates the parameter names against the expected names for the appropriate lines + 'in the "names" folder, and for the folder values, validates the existence of the folders. The + 'function returns "True" if the "names" file is found and the parameter names and values read from + 'the names file can be validated against the expected values or the existence of the appropriate + 'folders. The function returns "False" if the "names" file cannot be found or read, if any of the + 'parameter names or values cannot be validated, or if there is any other problem in the function. + ' + 'NOTE: The log file name parameter value is validated outside of this function, when the log file + ' is first opened. + ' + ' Inputs: + ' All paramters are by-reference outputs whose values are read from the "names" file. + ' Outputs: + ' Error messages, log file entries. + ' Function return: The function returns "True" if the "names" file is found and can be + ' read and all of the parameters and values are appropriate. + ' strDSfolderName: Passes the name of the datasheet file folder by reference from + ' the validated value read from the "names" file. + ' strLogFileName: Passes the name of the log file by reference from the validated + ' value read from the "names" file. + ' strLogFileLoc: Passes the name of the log file folder by reference from the + ' validated value read from the "names" file. + ' strMoveLoc: Passes the name of the invalid file "move" folder by reference from + ' the validated value read from the "names" file. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strNamesFileLoc As String 'Location (folder) of the "names" file. + Dim strNamesFileNameLoc As String 'Name and location (folder) of the "names" file. + Dim strMessageString As String 'String for error message from reading "names" file lines. + Dim strParmName As String 'Parameter name read from the "names" file. + Dim strParmValue As String 'Parameter value read from the "names" file. + Dim strParmNameExpected As String 'Parameter value expected from the "names" file. + Dim iLineNumber As Integer 'Number of line read from the "names" file. + Dim iNamesFileHandle As Integer 'File number (file "handle") of the "names" file. + Dim objFSO As FileSystemObject 'File system object for "names" file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Get next valid file number (file + 'handle) for the "names" file. + iNamesFileHandle = FreeFile + + 'Initialize. + strMessageString = "" 'Initialize as null (blank) string. + functionNamesFileReadOK = True 'Initialize as "all file entries read OK". + strDSfolderName = "" 'Set string to null. + strLogFileName = "" 'Set string to null. + strLogFileLoc = "" 'Set string to null. + strMoveLoc = "" 'Set string to null. + + 'Set file name and location from hardcoded constants. + strNamesFileLoc = NAMES_FILE_LOC 'Set "names" file folder to defined location. + If Right$(strNamesFileLoc, 1) <> "\" Then strNamesFileLoc = strNamesFileLoc & "\" 'Add trailing backslash (if needed). + strNamesFileNameLoc = strNamesFileLoc & NAMES_FILE_NAME 'Add "names" file name to folder. + + 'Check for existence of "names" file folder. + If Not funcFolderExists(strNamesFileLoc, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strNamesFileLoc & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Check for existence of the "names" file. + If Not (objFSO.FileExists(strNamesFileNameLoc)) Then + 'File not found. Post error return, display + 'error message, and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The ""names"" file: " & strNamesFileNameLoc & " was not found!" & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Destroy the file system object (it is + 'not used later in the function). + Set objFSO = Nothing + + 'Open the "names" file for input (reading line by line). + Open strNamesFileNameLoc For Input As iNamesFileHandle + + 'Read lines of the "names" file and check parameter names and values. + For iLineNumber = 1 To 4 + 'Set expected parameter names. + If (iLineNumber = 1) Then strParmNameExpected = "DATASHEET FOLDER NAME" + If (iLineNumber = 2) Then strParmNameExpected = "INVALID FILE MOVE FOLDER" + If (iLineNumber = 3) Then strParmNameExpected = "LOG FILE NAME" + If (iLineNumber = 4) Then strParmNameExpected = "LOG FILE FOLDER" + 'Get line of two comma-separated values and put into variables. + Input #iNamesFileHandle, strParmName, strParmValue + 'Trim the values read. + strParmName = Trim(strParmName) + strParmValue = Trim(strParmValue) + If (strParmName = strParmNameExpected) Then + 'Expected parameter name is found. + 'If the parameter is a location (folder) + 'paramter, check if the folder exists. + If (iLineNumber <> 3) Then + 'Folder parameter. Add a trailing backslash, if necessary. + If Right$(strParmValue, 1) <> "\" Then strParmValue = strParmValue & "\" + 'Check if folder exists. + If Not funcFolderExists(strParmValue, HIDE_MESSAGES) Then + 'Folder not found. Post function error return, display an + 'error message (here, not in the "folder exists" function, + 'due to the "False" parameter), and exit this function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "Folder not found: " & strParmValue & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + End If + Else + 'The parameter name read from the "names" file does not match the + 'expected value. Post error return, display error message, + 'and exit function. + functionNamesFileReadOK = False 'Error return value for function. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & vbCrLf & _ + "The parameter read from the ""names"" file" & vbCrLf & _ + "does not match the expected value!" & vbCrLf & _ + "Parameter read: " & strParmName & vbCrLf & _ + "Parameter expected: " & strParmNameExpected & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + Exit Function + End If + + 'Set parameter values to appropriate variables. + If (iLineNumber = 1) Then strDSfolderName = strParmValue + If (iLineNumber = 2) Then strMoveLoc = strParmValue + If (iLineNumber = 3) Then strLogFileName = strParmValue + If (iLineNumber = 4) Then strLogFileLoc = strParmValue + Next iLineNumber + + 'Close the "names" file. + Close #iNamesFileHandle + + Exit Function 'Exit the function (before the error handler) if no error. +ErrorHandler: + Close #iNamesFileHandle 'Close the "names" file. + Set objFSO = Nothing 'Destroy the file system object. + functionNamesFileReadOK = False 'Error return value. + MsgBox ("Error in ""functionNamesFileReadOK"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcOpenLogFile(ByVal strLogFileName As String, ByVal strLogFileLoc As String, _ + ByVal iLogFileHandle As Integer) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function opens the log file specified by the passed file name and folder for append using the + 'passed file "handle". The function returns "True" if there is no problem opening the file, and + 'returns "False" if any problem occurs. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFullFileName As String + + On Error GoTo ErrorHandler + + 'Make sure the folder name includes a trailing "\", then create + 'full file name (file name including folder) and open the file + 'for append. + If Right$(strLogFileLoc, 1) <> "\" Then strLogFileLoc = strLogFileLoc & "\" + strFullFileName = strLogFileLoc & strLogFileName 'Create full file name (name with location). + Open strFullFileName For Append As iLogFileHandle 'Open log file for append. + funcOpenLogFile = True 'Return value indicating no problems opening the file. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcOpenLogFile = False 'Error value. + MsgBox ("Error in ""funcOpenLogFile"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subFileOpenMessage(ByVal strLogFileNameLoc As String) + '---------------------------------------------------------------------------------------------------- + 'Subroutine to display error message about opening the log file using the passed full log file name + '(the file name complete with its directory location). + '---------------------------------------------------------------------------------------------------- + ' + MsgBox ("Error opening log file: " & strLogFileNameLoc & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcFolderExists(ByVal strFolderName As String, ByVal bDisplayErrMsg As Boolean) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed folder exists, and "False" if it does not, or there is + 'any other problem with the function. The passed flag displays a "file not found" message if "True", + 'or skips the message if "false" (for example, if a calling routine has its own error message). + '---------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Make sure the folder name includes a trailing "\". + If Right$(strFolderName, 1) <> "\" Then strFolderName = strFolderName & "\" + + 'Check whether the folder exists. + If Not objFSO.FolderExists(strFolderName) Then + funcFolderExists = False 'Return value for "folder not found". + If (bDisplayErrMsg) Then + 'Display error message if the flag is "True". + MsgBox ("Folder not found: " & strFolderName & " in " & vbCrLf & _ + PROGRAM_DESCRIP & " (" & PROGRAM_NAME & "), Version: " & PROGRAM_VERSION & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical + End If + Else + funcFolderExists = True 'Return value for "folder found". + End If + + Set objFSO = Nothing 'Destroy file system object. + + Exit Function ' Exit before error handler. +ErrorHandler: + funcFolderExists = False 'Error value. + Set objFSO = Nothing 'Destroy file system object. + MsgBox ("Error in ""funcFolderExists"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subProcessDSfolder(ByVal strFolderName As String, ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, _ + ByVal iLogFileHandle As Integer, ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long, _ + ByRef lCountAll As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the datasheet (and possibly other) files in the passed folder. The subroutine + 'initializes counts, writes a header to log file specified by the passed log file name and location, + 'and performs a directory listing of the passed folder, processing each file name through using + 'the "subProcessDSfile" subroutine to determine whether the file is an invalid datasheet file, in + 'which case the file is moved to the passed "move location" and this action is logged to the log file, + 'or is a valid DOS-encoded datasheet file name for datasheets with a work order number value greater + 'than "99,999", in which case the file is renamed to the "unecoded" datasheet file name and this + 'action is logged to the log file. Finally, the counts of the number of moved (invalid) files, renamed + 'files, and total of files in the directory are logged to the log file. + ' + ' Inputs: + ' strFolderName: Datasheet folder location. + ' strDSmoveLocation: Directory location that invalid files are moved. Invalid files include non-text + ' files and files with names that do not match the format for the Dataforth website. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountAll: Passes initial count of all files found in the datasheet folder to + ' the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountAll: Passes the count of all files found in the datasheet file folder + ' back to the calling routine by reference for status displays, etc. + ' Also used, on first call, to pass the initial count from the calling + ' routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strFileName As String + Dim strFullFileName As String + Dim strDirSpec As String + + On Error GoTo ErrorHandler + + 'Initialize. + lCountInvalidTotal = 0 + lCountRenameTotal = 0 + lCountInvalidGood = 0 + lCountRenameGood = 0 + lCountAll = 0 + + 'Set Dir$ function specification (directory path and search criteria). + 'strDirSpec = strFolderName & "\*.txt" + strDirSpec = strFolderName & "\*.*" + strFileName = Dir$(strDirSpec, vbNormal) + + 'Loop through each file in the folder + Do While (strFileName <> "") + strFileName = Dir$ + If (strFileName <> "") Then + Call subProcessDSfile(strFileName, strFolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + lCountAll = lCountAll + 1 'Increment total count. + frmSplash.lblFileCount.Caption = lCountAll + frmSplash.lblCurrentFile.Caption = strFileName + frmSplash.lblFileCount.Refresh + frmSplash.lblCurrentFile.Refresh + End If + Loop + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfolder"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Sub subProcessDSfile(ByVal strDSfileName As String, ByVal strDSfolderName As String, ByVal strDSmoveLocation As String, _ + ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer, _ + ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to process the passed file name. If it is determined to be an invalid name for the Dataforth + 'website, the file is moved to the passed directory location and this action is recorded in a log file + 'whose name and location is also passed as a parameter. If the file name matches the format of "encoded" + 'datasheet file names from the DOS test programs, the file is renamed to the appropriate "unencoded" + 'datasheet file name and this action is also recorded to the specified log file. The subroutine posts + 'error messages for problems that may be encountered during file processing, and passes file counts + '(total files found to be renamed or moved, files successfully rename or moved) to the calling routine. + ' + ' Inputs: + ' strDSfileName: Datasheet file name. + ' strDSmoveLocation: Directory location that invalid files are moved. Invalid files include non-text + ' files and files with names that do not match the format for the Dataforth website. + ' strDSlogNameLoc: Directory location and file name of log file to record datasheet file moves and + ' renames. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the local variables. + Dim strWorkOrderNum As String 'Work order number. + Dim strFullFileName As String 'Full file name (including extension). + Dim strFileNameOnly As String 'File name (only). + Dim iDashLoc As Integer 'Dash location in file name (only) string. + Dim iFNOlength As Integer 'Length of file name (only) string. + Dim strWOdecoded As String 'Work order number. + + On Error GoTo ErrorHandler + + 'Get uppercase-only version of the full file name. + 'This is necessary for later processing of the + 'datasheet files (including determining whether + 'they are validly-named datasheet files). + strFullFileName = UCase$(strDSfileName) + + 'Get the file name (only). This should be the (encoded + 'or unencoded) module serial number. Note that the + 'function requires a full file name already in + 'all-UPPERCASE. + strFileNameOnly = funcGetFileNameOnly(strFullFileName) + + 'Check for text file. + If (strFileNameOnly = "") Then + 'Not a text file (null return from funcGetFileNameOnly). + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-text file. + End If + + 'Check for valid dash location (and/or existence) and a valid dash number. + iDashLoc = funcGetDashLoc(strFileNameOnly) 'Get dash location. + + 'Check for valid location. + If Not (funcGetDashLoc(strFileNameOnly) > 0) Then + 'Dash (or dash number) is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + + 'Parse work order# (characters to the left of + 'the dash) from the serial number string. + strWorkOrderNum = Left$(strFileNameOnly, iDashLoc - 1) + + If (funcIsAllNumbers(strWorkOrderNum) = True) Then + 'Work order number string is all numbers, + 'check for leading "0". + If (Left$(strWorkOrderNum, 1) = "0") Then + 'Leading "0" in all-numeric work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + Else + 'Work order string is not all numbers. Check if + 'it is matches the format of a DOS-encoded work + 'order number. + If (funcISrenameWO(strWorkOrderNum) = True) Then + 'DOS-encoded work order number. Rename file + 'to unencoded datasheet file name. + Call subDSmoveRename(RENAME_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Else + 'Not a DOS-encoded work order number. Work order number is not valid. + 'Move file to specified location and log action to specified log file. + Call subDSmoveRename(MOVE_FILE, strFullFileName, strDSfolderName, strDSmoveLocation, strDSlogNameLoc, iLogFileHandle, _ + lCountInvalidTotal, lCountRenameTotal, lCountInvalidGood, lCountRenameGood) + Exit Sub 'Exit early for non-datasheet file (no or invalid dash or invalid dash number). + End If + End If + + Exit Sub 'Exit before error handler. +ErrorHandler: + MsgBox ("Error in ""subProcessDSfiles"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Sub + +Private Function funcGetFileNameOnly(ByVal strFullFileName As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns the file name (only) portion of the full file name (file name plus extension). + 'The file name, in the case of datasheet files, is the module serial number. This is returned + 'if the proper file extension is found (".TXT"). If the proper extension is not found, + 'or there is some other problem (such as a blank file name passed to the function), a null string + 'is returned. + ' + 'NOTE: The passed full file name must be in all-UPPERCASE for the ".TXT" check to work. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strSerial As String 'Serial number portion of the complete file name (file name, without the extension). + Dim iSTRlength As Integer 'Length of serial number or complete file name string. + + On Error GoTo ErrorHandler + + If (strFullFileName <> "") Then + 'Get serial number (file name) from complete file name. + If (Right$(strFullFileName, 4) = ".TXT") Then + 'Strip off last four characters (.TXT file extension) from full file name + 'to create the file name only (serial number) string. + iSTRlength = Len(strFullFileName) 'Get length of the full file name. + strSerial = Left$(strFullFileName, iSTRlength - 4) 'Strip off last four characters (".txt"). + funcGetFileNameOnly = strSerial + Else + funcGetFileNameOnly = "" 'Error value. + End If + Else + 'Invalid (null) file name. + funcGetFileNameOnly = "" 'Error value. + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcGetFileNameOnly = "" 'Error value. + MsgBox ("Error in ""funcGetFileNameOnly"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Function funcIsAllNumbers(ByVal strTestString As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'Function that checks whether the passed string consists of only numerical characters. The function + 'returns "True" if each character in the string is a number, and "False" if any character is not + 'a number or if there is some other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strChar As String + Dim iDx As Integer + + On Error GoTo ErrorHandler + + 'Initialize to "all numbers" value. + funcIsAllNumbers = True + + For iDx = 1 To Len(strTestString) 'Loop from 1st character to last character of string. + 'See if the next character is a non-number. + strChar = Mid$(strTestString, iDx, 1) 'Get next character. + If ((strChar < "0") Or (strChar > "9")) Then 'Character is not "0" through "9". + funcIsAllNumbers = False 'Set "not all numbers" value. + Exit For 'Exit the loop (no need to continue after first non-number). + End If + Next iDx + + Exit Function ' Exit before error handler. +ErrorHandler: + funcIsAllNumbers = False 'Error ("not all numbers") value. + MsgBox ("Error in ""funcIsAllNumbers"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcGetDashLoc(ByVal strFileNameOnly As String) As Integer + '---------------------------------------------------------------------------------------------------- + 'This function returns the dash ("-") location in the passed file name (only) string. It returns + 'an error value of "0" if no dash is found, or more than one dash is found, if there are more + 'than one characters after the dash, and if any of the characters after the dash are not a + 'number, or if there are any other problems in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim iSTRlength As Integer 'Length of serial number string. + Dim iDashLocL As Integer 'Location of dash, when searched for from the left. + Dim iDashLocR As Integer 'Location of dash, when searched for from the right. + Dim strDashNum As String 'Dash number string. + + On Error GoTo ErrorHandler + + iSTRlength = Len(strFileNameOnly) 'Length of file name (only) string. + + 'Location of dash (characters from start (left) of string) when searched from the left. + iDashLocL = InStr(strFileNameOnly, "-") + + 'Location of dash (characters from start (left) of string) when searched from the right. + iDashLocR = InStrRev(strFileNameOnly, "-") + + If (iDashLocL = iDashLocR) Then + 'Dash in same location = only one dash in the string. + ' + 'Start dash location validation. + If (((iSTRlength - iDashLocL) > 2) Or ((iSTRlength - iDashLocL) = 0)) Then + 'Too many characters after the dash, or dash at end (dash number + 'more than two characters, or less than one). + funcGetDashLoc = 0 'Error value (invalid dash). + Else + 'Dash number is one or two characters. Get for an all-number dash number. + strDashNum = Mid$(strFileNameOnly, iDashLocL + 1, iSTRlength - iDashLocL) + If (funcIsAllNumbers(strDashNum) = True) Then + 'Dash number is all numbers. + funcGetDashLoc = iDashLocL 'Good value (valid dash). + Else + 'Dash number is not valid (not all numbers). + funcGetDashLoc = 0 'Error value (invalid dash). + End If + End If + Else + 'More than one dash in the serial string. + funcGetDashLoc = 0 'Error value (invalid dash). + End If + + Exit Function 'Exit before error handler. +ErrorHandler: + funcGetDashLoc = 0 'Error (not valid) value. + MsgBox ("Error in ""funcIsValidDash"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcDecodeWOchar(ByVal strWOnum As String) As String + '---------------------------------------------------------------------------------------------------- + 'This function returns a two-character string decoded from the first character of the + 'passed work order number string. If the first character is "A" through "J", the + 'function returns "10" through "19", respectively, which represents the values that + 'are encoded in valid DOS-encoded datasheet file names. If the first character is + 'not "A" or "J" or a letter in between, or if there is some problem in the function, + 'the function returns a null string. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strFirstChar As String 'First character in passed work order number string. + + On Error GoTo ErrorHandler + + If (strWOnum = "") Then + 'Null string, return error value (null string). + funcDecodeWOchar = "" 'Error value. + Else + 'String has at least one character, check for "A" through "J". + strFirstChar = Left$(strWOnum, 1) 'Get first character of passed work order number. + If (strFirstChar = "A") Then + funcDecodeWOchar = "10" 'Decode of first character. + ElseIf (strFirstChar = "B") Then + funcDecodeWOchar = "11" 'Decode of first character. + ElseIf (strFirstChar = "C") Then + funcDecodeWOchar = "12" 'Decode of first character. + ElseIf (strFirstChar = "D") Then + funcDecodeWOchar = "13" 'Decode of first character. + ElseIf (strFirstChar = "E") Then + funcDecodeWOchar = "14" 'Decode of first character. + ElseIf (strFirstChar = "F") Then + funcDecodeWOchar = "15" 'Decode of first character. + ElseIf (strFirstChar = "G") Then + funcDecodeWOchar = "16" 'Decode of first character. + ElseIf (strFirstChar = "H") Then + funcDecodeWOchar = "17" 'Decode of first character. + ElseIf (strFirstChar = "I") Then + funcDecodeWOchar = "18" 'Decode of first character. + ElseIf (strFirstChar = "J") Then + funcDecodeWOchar = "19" 'Decode of first character. + Else + 'Not "A" through "J" + funcDecodeWOchar = "" 'Error value. + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcDecodeWOchar = "" 'Error value. + MsgBox ("Error in ""funcDecodeWOchar"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Function funcISrenameWO(ByVal strWOnumber As String) As Boolean + '---------------------------------------------------------------------------------------------------- + 'This function returns "True" if the passed work order number matches the format of a DOS-encoded + 'work order number (for work orders above the value of "99,999"). A DOS-encoded work order number + 'will be five characters long, start with "A" through "J", and have all numbers for the remaining + 'characters. The function will return "False" if any of these conditions are not true, or there is + 'any other problem in the function. + '---------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLastFour As String + Dim strFirstOne As String + + On Error GoTo ErrorHandler + + If (Len(strWOnumber) <> 5) Then + 'Not five characters long. + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strFirstOne = UCase$(Left$(strWOnumber, 1)) + If ((strFirstOne < "A") Or (strFirstOne > "J")) Then + 'First character not "A" through "J". + funcISrenameWO = False 'Set "not a valid rename string" value. + Else + strLastFour = Right$(strWOnumber, 4) + If (funcIsAllNumbers(strLastFour) = True) Then + funcISrenameWO = True 'Set "valid rename string" value. + Else + 'Last four characters not all numberss. + funcISrenameWO = False 'Set "not a valid rename string" value. + End If + End If + End If + + Exit Function ' Exit before error handler. +ErrorHandler: + funcISrenameWO = False 'Error value (not valid "rename" string). + MsgBox ("Error in ""funcISrenameWO"" = " & Err.Description & vbCrLf & vbCrLf & _ + "Contact engineering before proceeding!"), vbCritical +End Function + +Private Sub subDSmoveRename(ByVal bMoveFile As Boolean, ByVal strFullFileName As String, ByVal strDSfolderName As String, _ + ByVal strDSmoveLocation As String, ByVal strDSlogNameLoc As String, ByVal iLogFileHandle As Integer, _ + ByRef lCountInvalidTotal As Long, ByRef lCountRenameTotal As Long, _ + ByRef lCountInvalidGood As Long, ByRef lCountRenameGood As Long) + '------------------------------------------------------------------------------------------------------------- + 'Subroutine to move or rename the file specified by the passed file name and datasheet file folder. If the + 'move/rename parameter ("bMoveFile") is "True", the file is moved to the directory specified by the + 'passed "move" folder name. If the parameter is "False", the file is renamed from the DOS-encoded name to + 'the unencoded datasheet file name. In both cases, the "move" or "rename" is accomplished by copying the + 'file to the new name or location, and then deleting the old file if nothing has gone wrong. All actions, + 'including successful moves or renames, unsuccessful file copies, or unsuccessful file deletions, are + 'recorded in a log file whose name and location, as well as its file number (file "handle"), are passed + 'as parameters. The subroutine increments by-reference count parameters for each invalid or DOS-encoded + 'datasheet file found and for each successful file move or rename. These can be used for a status displays, + 'such as "total invalid files" or "total renamed files", or similar, and can include lines in the log file + 'footer after the program has completed processing the files in the datasheet file folder. Errors encountered + 'during the subroutine will be logged in the specified log file rather than displayed to the screen, since + 'screen display would cause problems due to the number of files typically processed in the datasheet file + 'folder. + ' + 'NOTE: Since the existence of all of the relevant directories is verified by one of the calling routines + ' directory checking is not repeated here to save program time (since this function is called for + ' every relevant file). + ' + ' Inputs: + ' bMoveFile: This parameter is "True" to move the specified file to the "move" + ' folder (usually used for invalid files in the datasheet file + ' folder), or "False" to rename the specified file from the + ' DOS-encoded work order number (for values above "99,999") to the + ' unencoded work order number (file name matching the module serial + ' number contained within the datasheet file). + ' strFullFileName: Full file name of the file to be moved (includes file extension). + ' strDSfolderName: Datasheet folder location. + ' strDSmoveLocation: Directory location where the file is moved. + ' strDSlogNameLoc: Directory location and file name of log file to record the file move. + ' iLogFileHandle: File "handle" (file number) for log file. + ' lCountInvalidTotal: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameTotal: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' lCountInvalidGood: Passes initial count of invalid datasheet files (files to be moved) + ' to the subroutine. Also used to pass total count back to the calling + ' routine for status displays (see entry in "Outputs", below). + ' lCountRenameGood: Passes initial count of renamed datasheet files to the subroutine. + ' Also used to pass total count back to the calling routine for status + ' displays or log file footer (see entry in "Outputs", below). + ' Outputs: + ' Error messages, log file entries. + ' lCountInvalidTotal: Passes count of invalid datasheet files found back to the calling + ' routine by reference for status displays, log file footer, etc. + ' Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameTotal: Passes count of DOS-encoded datasheet files found back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountInvalidGood: Passes count of successfully moved invalid datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + ' lCountRenameGood: Passes count of successfully renamed DOS-encoded datasheet files back to + ' the calling routine by reference for status displays, log file footer, + ' etc. Also used, on first call, to pass the initial count from the + ' calling routine (see entry in "Inputs", above). + '------------------------------------------------------------------------------------------------------------- + ' + 'Define the variables. + Dim strLogFileLine As String 'String for a line of information for the log file. + Dim strFullFileRename As String 'Full file name (name and extension) for the renamed (unencoded) datasheet file name. + Dim strFullFileNameLoc As String 'Full file name (name and extension) and folder of the file in the datasheet folder. + Dim strFullFileRenameLoc As String 'Full file name (name and extension) and folder for the renamed (unencoded) datasheet file name. + Dim strRenameFirstChars As String 'First character of file to be renamed, or (decoded) first two characters of renamed file. + Dim iLenFullFileName As Integer 'Length of the full file name of the file to be renamed. + Dim objFSO As FileSystemObject 'File system object for log file. + + On Error GoTo ErrorHandler + + 'Initialize strings to null. + strLogFileLine = "" + strFullFileRename = "" + strFullFileNameLoc = "" + strFullFileRenameLoc = "" + strRenameFirstChars = "" + + 'Increment the count of the total (found) files of the appropriate type. + If (bMoveFile) Then + 'Increment count of invalid datasheet files (files to move) found in datasheet folder. + lCountInvalidTotal = lCountInvalidTotal + 1 + Else + 'Increment count of DOS-encoded datasheet files (files to rename) found in datasheet folder. + lCountRenameTotal = lCountRenameTotal + 1 + End If + + 'Create an instance of the FileSystemObject (project must reference the + 'Windows Scripting Library: Scrrun.dll). + Set objFSO = CreateObject("Scripting.FileSystemObject") + + 'Create the full file name and location from the full file + 'name and the folder location. First, add a trailing + 'backslash, if needed, to the folder location. + If Right$(strDSfolderName, 1) <> "\" Then strDSfolderName = strDSfolderName & "\" + strFullFileNameLoc = strDSfolderName & strFullFileName + + 'If the file needs to be renamed, create the full "rename" file name + '(file name and extension) from the original DOS-encoded name, then + 'create the full name/location (file name and folder location). + If Not (bMoveFile) Then + 'File to be renamed. Decode first character of full file name. + strRenameFirstChars = Left$(strFullFileName, 1) 'Get first character of file to be renamed. + iLenFullFileName = Len(strFullFileName) 'Get the length of the full file name of the file to be renamed. + 'Use the "decode work order character" function to decode the first character of the full + 'file name of the file to be renamed (note, the function name implies the passed string + 'is the work order number only, but since the function only uses the first character of + 'the string, it also works for the full file name). + strRenameFirstChars = funcDecodeWOchar(strFullFileName) 'Get decoded first two characters of full file name. + 'Create the renamed file name, by combining the new decoded characters with the characters of the full + 'datasheet file name to be renamed, but skipping the first character. + strFullFileRename = Right$(strFullFileName, iLenFullFileName - 1) 'Get full file name minus the first character. + strFullFileRename = strRenameFirstChars & strFullFileRename 'Create full rename file name by adding decoded characters. + strFullFileRenameLoc = strDSfolderName & strFullFileRename 'Create full rename file name/location by adding folder. + End If + + 'Create "could not copy" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the CopyFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "copy good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not copy" message. + strLogFileLine = "Could not copy file: " & strFullFileNameLoc & " to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not copy file: " & strFullFileNameLoc & " to: " & strFullFileRename + End If + + 'Copy the invalid file or file to be renamed in the datasheet folder. + 'For moves, copy to the "move" directory. For rename, copy to a new + 'name in the same folder. File copy parameters: + 'source (full file name/loc), destination (folder + 'only or full (rename) file name/loc), "True" for + 'overwrite if a file of same name already exists + 'in the destination. + If (bMoveFile) Then + 'Move invalid file. Start by copying to new folder location. + Call objFSO.CopyFile(strFullFileNameLoc, strDSmoveLocation, True) + Else + 'Rename DOS-encoded datasheet file. Start by copying to name in same folder. + Call objFSO.CopyFile(strFullFileNameLoc, strFullFileRenameLoc, True) + End If + + 'Create "could not delete" message for log file. + 'NOTE: This is done BEFORE the copy is attempted, because the DeleteFile method + ' throws an error if it fails, which is the only way an unsuccesful + ' operation can be detected. This message is then printed to the log + ' file in the error handler. Any "delete good" message will have to wait + ' until after all operations, just before the error handler, to be + ' run only if there are no errors. + If (bMoveFile) Then + 'Invalid file "could not delete" message. + strLogFileLine = "Could not delete file: " & strFullFileNameLoc & " after copy to: " & strDSmoveLocation + Else + 'Rename file "could not delete" message. + strLogFileLine = "Could not delete file: " & strFullFileNameLoc & " after copy to: " & strFullFileRename + End If + + + + 'Delete the invalid file in the datasheet folder. + 'File delete parameters: full file/loc, "True" + 'for "force" (ignore read-only). + Call objFSO.DeleteFile(strFullFileNameLoc, True) + + 'Since there were no problems to this point (no jump to the error handler), + 'create "successfully moved" or "successfully renamed" message, increment + 'the appropriate count, and write the message to the log file. + If (bMoveFile) Then + strLogFileLine = "Moved file: " & strFullFileNameLoc & " to: " & strDSmoveLocation + lCountInvalidGood = lCountInvalidGood + 1 'Increment count of successfully moved files. + Else + strLogFileLine = "Renamed file: " & strFullFileNameLoc & " to: " & strFullFileRename + lCountRenameGood = lCountRenameGood + 1 'Increment count of successfully renamed files. + End If + Print #iLogFileHandle, strLogFileLine 'Write line to log file. + + Set objFSO = Nothing 'Destroy file system object. + + Exit Sub ' Exit before error handler. +ErrorHandler: + Print #iLogFileHandle, strLogFileLine 'Write previously-generated error message to log file. + Set objFSO = Nothing 'Destroy file system object. + 'NOTE: Since this function processes many files, errors should be posted (only) to the log + ' file, NOT to the screen. Therefore, the following two lines (single line of code) + ' are (is) commented out. + 'MsgBox ("Error in ""subDSmoveRename"" = " & Err.Description & vbCrLf & vbCrLf & _ + ' "Contact engineering before proceeding!"), vbCritical +End Sub + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.vbp b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.vbp new file mode 100644 index 0000000..540b885 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.vbp @@ -0,0 +1,46 @@ +Type=Exe +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Reference=*\G{36F6E2F6-A9CE-11D4-98E5-00108301CB39}#1.0#0#..\..\Program Files (x86)\Agilent\IO Libraries Suite\bin\AgtRM.dll#Agilent VISA COM Resource Manager 1.0 +Reference=*\G{DB8CBF00-D6D3-11D4-AA51-00A024EE30BD}#1.0#0#..\..\Program Files (x86)\IVI Foundation\VISA\VisaCom\GlobMgr.dll#VISA COM 1.0 Type Library +Reference=*\G{6B263850-900B-11D0-9484-00A0C91110ED}#1.0#0#..\..\Windows\SysWOW64\MSSTDFMT.DLL#Microsoft Data Formatting Object Library 6.0 (SP4) +Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao350.dll#Microsoft DAO 3.51 Object Library +Reference=*\G{3D5C6BF0-69A3-11D0-B393-00A0C9055D8E}#1.0#0#..\..\Program Files (x86)\Common Files\designer\MSDERUN.DLL#Microsoft Data Environment Instance 1.0 +Reference=*\G{00000200-0000-0010-8000-00AA006D2EA4}#2.0#0#..\..\Program Files (x86)\Common Files\System\ado\msado20.tlb#Microsoft ActiveX Data Objects 2.0 Library +Reference=*\G{642AC760-AAB4-11D0-8494-00A0C90DC8A9}#1.0#0#..\..\Windows\SysWow64\MSDBRPTR.DLL#Microsoft Data Report Designer v6.0 +Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#..\..\Windows\SysWOW64\scrrun.dll#Microsoft Scripting Runtime +Object={BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0; tabctl32.ocx +Module=A_Main; DFWDS.bas +Form=frmSplash.frm +Startup="Sub Main" +HelpFile="" +Title="DFWDS" +ExeName32="DFWDS.exe" +Command32="" +Name="DFWDS" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=1 +RevisionVer=1 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Dataforth Corporation" +CompilationType=0 +OptimizationType=1 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 +DebugStartupOption=0 + +[MS Transaction Server] +AutoRefresh=1 diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.vbw b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.vbw new file mode 100644 index 0000000..f62f99f --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/DFWDS.vbw @@ -0,0 +1,2 @@ +A_Main = 50, 50, 1076, 422, Z +frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/Dataforth.ico b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/Dataforth.ico new file mode 100644 index 0000000..76fff6d Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/Dataforth.ico differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/frmSplash.frm b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/frmSplash.frm new file mode 100644 index 0000000..ea07586 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/frmSplash.frm @@ -0,0 +1,204 @@ +VERSION 5.00 +Begin VB.Form frmSplash + AutoRedraw = -1 'True + BorderStyle = 3 'Fixed Dialog + ClientHeight = 4344 + ClientLeft = 252 + ClientTop = 1416 + ClientWidth = 7428 + ClipControls = 0 'False + ControlBox = 0 'False + Icon = "frmSplash.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form2" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 4344 + ScaleWidth = 7428 + StartUpPosition = 2 'CenterScreen + Begin VB.Frame frmMainFrame + Height = 4332 + Left = 0 + TabIndex = 0 + Top = 0 + Width = 7425 + Begin VB.Label lblCurrentFile + Caption = "Insert current file here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 9 + Top = 3840 + Width = 2412 + End + Begin VB.Label lblFileCount + Caption = "Insert file count here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 8 + Top = 3480 + Width = 2412 + End + Begin VB.Label lblProgName + Caption = "Program Name:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 7 + Top = 1320 + Width = 2655 + End + Begin VB.Label lblName + Caption = "Insert pgm name here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 6 + Top = 1680 + Width = 3615 + End + Begin VB.Label lblVersion + Caption = "Insert version here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 5 + Top = 2400 + Width = 3615 + End + Begin VB.Image imgLogo + Height = 3105 + Left = 0 + Picture = "frmSplash.frx":030A + Stretch = -1 'True + Top = 240 + Width = 3015 + End + Begin VB.Label lblCopyright + Caption = "Copyright 2014" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 2 + Top = 3120 + Width = 2415 + End + Begin VB.Label lblCompany + Caption = "Dataforth Corporation" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 1 + Top = 2880 + Width = 2415 + End + Begin VB.Label lblVersionCaption + Caption = "Program Version:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 3 + Top = 2040 + Width = 2655 + End + Begin VB.Label C + Caption = "Processing Dataforth Datasheet Files" + BeginProperty Font + Name = "Arial" + Size = 18 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 915 + Index = 0 + Left = 3480 + TabIndex = 4 + Top = 360 + Width = 3720 + End + End +End +Attribute VB_Name = "frmSplash" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + Me.lblName.Caption = PROGRAM_NAME + Me.lblVersion.Caption = PROGRAM_VERSION + Me.lblFileCount.Caption = "" + Me.lblCurrentFile.Caption = "" +End Sub + + + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/frmSplash.frx b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/frmSplash.frx new file mode 100644 index 0000000..57b2e47 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/History/DFWDS_2014-10-01/frmSplash.frx differ diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/frmSplash.frm b/projects/dataforth-dos/dfwds-research/source/_Working/frmSplash.frm new file mode 100644 index 0000000..ea07586 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/source/_Working/frmSplash.frm @@ -0,0 +1,204 @@ +VERSION 5.00 +Begin VB.Form frmSplash + AutoRedraw = -1 'True + BorderStyle = 3 'Fixed Dialog + ClientHeight = 4344 + ClientLeft = 252 + ClientTop = 1416 + ClientWidth = 7428 + ClipControls = 0 'False + ControlBox = 0 'False + Icon = "frmSplash.frx":0000 + KeyPreview = -1 'True + LinkTopic = "Form2" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 4344 + ScaleWidth = 7428 + StartUpPosition = 2 'CenterScreen + Begin VB.Frame frmMainFrame + Height = 4332 + Left = 0 + TabIndex = 0 + Top = 0 + Width = 7425 + Begin VB.Label lblCurrentFile + Caption = "Insert current file here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 9 + Top = 3840 + Width = 2412 + End + Begin VB.Label lblFileCount + Caption = "Insert file count here..." + BeginProperty Font + Name = "Arial" + Size = 10.2 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 252 + Left = 240 + TabIndex = 8 + Top = 3480 + Width = 2412 + End + Begin VB.Label lblProgName + Caption = "Program Name:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 7 + Top = 1320 + Width = 2655 + End + Begin VB.Label lblName + Caption = "Insert pgm name here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 6 + Top = 1680 + Width = 3615 + End + Begin VB.Label lblVersion + Caption = "Insert version here...." + BeginProperty Font + Name = "Arial" + Size = 9.6 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 5 + Top = 2400 + Width = 3615 + End + Begin VB.Image imgLogo + Height = 3105 + Left = 0 + Picture = "frmSplash.frx":030A + Stretch = -1 'True + Top = 240 + Width = 3015 + End + Begin VB.Label lblCopyright + Caption = "Copyright 2014" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 2 + Top = 3120 + Width = 2415 + End + Begin VB.Label lblCompany + Caption = "Dataforth Corporation" + BeginProperty Font + Name = "Arial" + Size = 8.4 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3480 + TabIndex = 1 + Top = 2880 + Width = 2415 + End + Begin VB.Label lblVersionCaption + Caption = "Program Version:" + BeginProperty Font + Name = "Arial" + Size = 12 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 285 + Left = 3480 + TabIndex = 3 + Top = 2040 + Width = 2655 + End + Begin VB.Label C + Caption = "Processing Dataforth Datasheet Files" + BeginProperty Font + Name = "Arial" + Size = 18 + Charset = 0 + Weight = 700 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 915 + Index = 0 + Left = 3480 + TabIndex = 4 + Top = 360 + Width = 3720 + End + End +End +Attribute VB_Name = "frmSplash" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Private Sub Form_Load() + Me.lblName.Caption = PROGRAM_NAME + Me.lblVersion.Caption = PROGRAM_VERSION + Me.lblFileCount.Caption = "" + Me.lblCurrentFile.Caption = "" +End Sub + + + diff --git a/projects/dataforth-dos/dfwds-research/source/_Working/frmSplash.frx b/projects/dataforth-dos/dfwds-research/source/_Working/frmSplash.frx new file mode 100644 index 0000000..57b2e47 Binary files /dev/null and b/projects/dataforth-dos/dfwds-research/source/_Working/frmSplash.frx differ diff --git a/projects/dataforth-dos/dfwds-research/swagger.json b/projects/dataforth-dos/dfwds-research/swagger.json new file mode 100644 index 0000000..ab96923 --- /dev/null +++ b/projects/dataforth-dos/dfwds-research/swagger.json @@ -0,0 +1,1789 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Dataforth Product API", + "description": "API for accessing Dataforth product catalog data", + "version": "v1" + }, + "paths": { + "/api/v1/Admin/refresh-cache": { + "post": { + "tags": [ + "Admin" + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshCacheResponseDto" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "500": { + "description": "Server Error" + } + } + } + }, + "/api/v1/Admin/cache-status": { + "get": { + "tags": [ + "Admin" + ], + "parameters": [ + { + "name": "appName", + "in": "query", + "schema": { + "type": "string", + "default": "dataforth.web" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CacheStatusResponseDto" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/Categories": { + "get": { + "tags": [ + "Categories" + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CategoryListItemDto" + } + } + } + } + } + } + } + }, + "/api/v1/Categories/{id}": { + "get": { + "tags": [ + "Categories" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CategoryDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/Categories/by-catalog-node/{catalogNodeId}": { + "get": { + "tags": [ + "Categories" + ], + "parameters": [ + { + "name": "catalogNodeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CategoryDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/OrderableProducts/{orderableProductId}/Attributes": { + "post": { + "tags": [ + "OrderableProducts" + ], + "parameters": [ + { + "name": "orderableProductId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateProductAttributeRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateProductAttributeRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateProductAttributeRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProductAttributeResponseDto" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "500": { + "description": "Server Error" + } + } + } + }, + "/api/v1/OrderableProducts/{orderableProductId}/Attributes/{attributeId}": { + "put": { + "tags": [ + "OrderableProducts" + ], + "parameters": [ + { + "name": "orderableProductId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "attributeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateProductAttributeRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateProductAttributeRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateProductAttributeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProductAttributeResponseDto" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "500": { + "description": "Server Error" + } + } + }, + "delete": { + "tags": [ + "OrderableProducts" + ], + "parameters": [ + { + "name": "orderableProductId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "attributeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "500": { + "description": "Server Error" + } + } + } + }, + "/api/v1/Products": { + "get": { + "tags": [ + "Products" + ], + "parameters": [ + { + "name": "productSeriesId", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "categoryId", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProductListItemDto" + } + } + } + } + } + } + } + }, + "/api/v1/Products/{id}": { + "get": { + "tags": [ + "Products" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProductDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/Products/by-part-number/{partNumber}": { + "get": { + "tags": [ + "Products" + ], + "parameters": [ + { + "name": "partNumber", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProductDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/product-series": { + "get": { + "tags": [ + "ProductSeries" + ], + "parameters": [ + { + "name": "categoryId", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SeriesListItemDto" + } + } + } + } + } + } + } + }, + "/api/v1/product-series/{id}": { + "get": { + "tags": [ + "ProductSeries" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/product-series/by-designation/{designation}": { + "get": { + "tags": [ + "ProductSeries" + ], + "parameters": [ + { + "name": "designation", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/product-series/by-catalog-node/{catalogNodeId}": { + "get": { + "tags": [ + "ProductSeries" + ], + "parameters": [ + { + "name": "catalogNodeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesDetailDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/ProductType": { + "get": { + "tags": [ + "ProductType" + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProductTypeListItemDto" + } + } + } + } + } + } + } + }, + "/api/v1/ProductType/{productTypeId}/products": { + "get": { + "tags": [ + "ProductType" + ], + "parameters": [ + { + "name": "productTypeId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OrderableProductDto" + } + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/v1/TestReportDataFiles": { + "post": { + "tags": [ + "TestReportDataFiles" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTestReportRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateTestReportRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateTestReportRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTestReportResponse" + } + } + } + }, + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTestReportResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDto" + } + } + } + } + } + }, + "get": { + "tags": [ + "TestReportDataFiles" + ], + "parameters": [ + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "pageSize", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 50 + } + }, + { + "name": "serialNumberPrefix", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "afterSerialNumber", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestReportDataFileListItemDtoPagedResultDto" + } + } + } + } + } + } + }, + "/api/v1/TestReportDataFiles/bulk": { + "post": { + "tags": [ + "TestReportDataFiles" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkCreateTestReportRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/BulkCreateTestReportRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/BulkCreateTestReportRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkCreateTestReportResponse" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDto" + } + } + } + } + } + } + }, + "/api/v1/TestReportDataFiles/{serialNumber}": { + "get": { + "tags": [ + "TestReportDataFiles" + ], + "parameters": [ + { + "name": "serialNumber", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestReportDataFileDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDto" + } + } + } + } + } + }, + "delete": { + "tags": [ + "TestReportDataFiles" + ], + "parameters": [ + { + "name": "serialNumber", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDto" + } + } + } + } + } + } + }, + "/api/v1/TestReportDataFiles/stats": { + "get": { + "tags": [ + "TestReportDataFiles" + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestReportDataFileStatsDto" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "BulkCreateTestReportRequest": { + "required": [ + "Items" + ], + "type": "object", + "properties": { + "Items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CreateTestReportRequest" + } + } + }, + "additionalProperties": false + }, + "BulkCreateTestReportResponse": { + "type": "object", + "properties": { + "TotalReceived": { + "type": "integer", + "format": "int32" + }, + "Created": { + "type": "integer", + "format": "int32" + }, + "Updated": { + "type": "integer", + "format": "int32" + }, + "Unchanged": { + "type": "integer", + "format": "int32" + }, + "Errors": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "CacheStatusResponseDto": { + "type": "object", + "properties": { + "AppName": { + "type": "string", + "nullable": true + }, + "PendingRefresh": { + "type": "boolean" + }, + "CheckedAt": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "CategoryDetailDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductSeries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProductSeriesListItemDto" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "CategoryListItemDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductSeriesCount": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateProductAttributeRequest": { + "required": [ + "AttributeType", + "Name" + ], + "type": "object", + "properties": { + "Name": { + "maxLength": 50, + "minLength": 0, + "type": "string" + }, + "Unit": { + "maxLength": 20, + "minLength": 0, + "type": "string", + "nullable": true + }, + "AttributeType": { + "minLength": 1, + "type": "string" + }, + "StringValue": { + "type": "string", + "nullable": true + }, + "NumberValue": { + "type": "number", + "format": "double", + "nullable": true + }, + "BooleanValue": { + "type": "boolean", + "nullable": true + }, + "DateValue": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "SortOrder": { + "type": "integer", + "format": "int32" + }, + "SortTier": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateTestReportRequest": { + "required": [ + "Content", + "SerialNumber" + ], + "type": "object", + "properties": { + "SerialNumber": { + "maxLength": 50, + "minLength": 0, + "type": "string" + }, + "Content": { + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "CreateTestReportResponse": { + "type": "object", + "properties": { + "SerialNumber": { + "type": "string", + "nullable": true + }, + "ContentHash": { + "type": "string", + "nullable": true + }, + "Created": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ErrorResponseDto": { + "type": "object", + "properties": { + "Message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "OrderableProductDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "PartNumber": { + "type": "string", + "nullable": true + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "OrderableProductGroupId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "WeightInGrams": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "ProductTypeId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "LifecycleStatus": { + "type": "string", + "nullable": true + }, + "PcnUrl": { + "type": "string", + "nullable": true + }, + "OrderingAvailability": { + "type": "string", + "nullable": true + }, + "Attributes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProductAttributeDto" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "ProblemDetails": { + "type": "object", + "properties": { + "type": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "status": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "instance": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": {} + }, + "ProductAttributeDto": { + "type": "object", + "properties": { + "ProductAttributeId": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Unit": { + "type": "string", + "nullable": true + }, + "AttributeType": { + "type": "string", + "nullable": true + }, + "StringValue": { + "type": "string", + "nullable": true + }, + "NumberValue": { + "type": "number", + "format": "double", + "nullable": true + }, + "BooleanValue": { + "type": "boolean", + "nullable": true + }, + "DateValue": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "SortOrder": { + "type": "integer", + "format": "int32" + }, + "SortTier": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "ProductAttributeResponseDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Unit": { + "type": "string", + "nullable": true + }, + "AttributeType": { + "type": "string", + "nullable": true + }, + "StringValue": { + "type": "string", + "nullable": true + }, + "NumberValue": { + "type": "number", + "format": "double", + "nullable": true + }, + "BooleanValue": { + "type": "boolean", + "nullable": true + }, + "DateValue": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "SortOrder": { + "type": "integer", + "format": "int32" + }, + "SortTier": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "ProductDetailDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "PartNumber": { + "type": "string", + "nullable": true + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "ProductSeriesId": { + "type": "integer", + "format": "int32" + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductSeriesCatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "PartNumberRoots": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, + "OrderableProducts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OrderableProductDto" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "ProductListItemDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "PartNumber": { + "type": "string", + "nullable": true + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "ProductSeriesId": { + "type": "integer", + "format": "int32" + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "ProductSeriesListItemDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductCount": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "ProductTypeListItemDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "RefreshCacheResponseDto": { + "type": "object", + "properties": { + "Success": { + "type": "boolean" + }, + "Message": { + "type": "string", + "nullable": true + }, + "RefreshedApps": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, + "LifecycleRecordsUpdated": { + "type": "integer", + "format": "int32" + }, + "RefreshRequestedAt": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "SeriesDetailDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductCategoryId": { + "type": "integer", + "format": "int32" + }, + "ProductCategoryCatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "Products": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SeriesProductDto" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "SeriesListItemDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductCategoryId": { + "type": "integer", + "format": "int32" + }, + "ProductCategoryCatalogNodeId": { + "type": "integer", + "format": "int32" + }, + "ProductCount": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "SeriesProductDto": { + "type": "object", + "properties": { + "Id": { + "type": "integer", + "format": "int32" + }, + "PartNumber": { + "type": "string", + "nullable": true + }, + "Name": { + "type": "string", + "nullable": true + }, + "Slug": { + "type": "string", + "nullable": true + }, + "CatalogNodeId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "TestReportDataFileDto": { + "type": "object", + "properties": { + "SerialNumber": { + "type": "string", + "nullable": true + }, + "Content": { + "type": "string", + "nullable": true + }, + "CreatedAtUtc": { + "type": "string", + "format": "date-time" + }, + "UpdatedAtUtc": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "additionalProperties": false + }, + "TestReportDataFileListItemDto": { + "type": "object", + "properties": { + "SerialNumber": { + "type": "string", + "nullable": true + }, + "CreatedAtUtc": { + "type": "string", + "format": "date-time" + }, + "UpdatedAtUtc": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "additionalProperties": false + }, + "TestReportDataFileListItemDtoPagedResultDto": { + "type": "object", + "properties": { + "Items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TestReportDataFileListItemDto" + }, + "nullable": true + }, + "TotalCount": { + "type": "integer", + "format": "int32" + }, + "Page": { + "type": "integer", + "format": "int32" + }, + "PageSize": { + "type": "integer", + "format": "int32" + }, + "NextCursor": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "TestReportDataFileStatsDto": { + "type": "object", + "properties": { + "TotalCount": { + "type": "integer", + "format": "int32" + }, + "LatestCreatedAtUtc": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "LatestUpdatedAtUtc": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateProductAttributeRequest": { + "required": [ + "AttributeType", + "Name" + ], + "type": "object", + "properties": { + "Name": { + "maxLength": 50, + "minLength": 0, + "type": "string" + }, + "Unit": { + "maxLength": 20, + "minLength": 0, + "type": "string", + "nullable": true + }, + "AttributeType": { + "minLength": 1, + "type": "string" + }, + "StringValue": { + "type": "string", + "nullable": true + }, + "NumberValue": { + "type": "number", + "format": "double", + "nullable": true + }, + "BooleanValue": { + "type": "boolean", + "nullable": true + }, + "DateValue": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "SortOrder": { + "type": "integer", + "format": "int32" + }, + "SortTier": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + } + }, + "securitySchemes": { + "oauth2": { + "type": "oauth2", + "flows": { + "authorizationCode": { + "authorizationUrl": "https://login.dataforth.com/connect/authorize", + "tokenUrl": "https://login.dataforth.com/connect/token", + "scopes": { + "openid": "OpenID", + "profile": "Profile", + "dataforth.web": "Dataforth API" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "openid", + "profile", + "dataforth.web" + ] + } + ] +} \ No newline at end of file