Session log + DFWDS Node port + Hoffman API uploader pipeline

Built the missing piece between the test datasheet pipeline and Dataforth's
new product API. End-to-end:

- Pulled DFWDS (Dataforth Web Datasheet System) VB6 source from
  AD1\Engineering\ENGR\ATE\Test Datasheets\DFWDS to local for analysis
- Decoded its filename validation: A-J prefix decodes (A=10..J=19), all-
  numeric WO# valid (no leading 0), anything else bad
- Ported the validation + move logic to Node (dfwds-process.js)
- Built bulk uploader (upload-delta.js) for Hoffman's Swagger API
  (POST /api/v1/TestReportDataFiles/bulk with OAuth client_credentials)

Sanitized 3 prior reference scripts (fetch-server-inventory, test-scenarios,
test-upload-two) to read CF_* env vars instead of hardcoded creds.

Live drain results:
- 897 files moved Test_Datasheets -> For_Web (all valid, no renames, no
  bad), DFWDS port summary in 1.1s
- Pushed entire For_Web (7,061 files) to Hoffman API in 49.7s @ 142/s:
  Created=803 Updated=114 Unchanged=6,144 Errors=0
- Server count: 489,579 -> 490,382 (+803 net new)

Also:
- Added clients/dataforth/.gitignore to exclude plaintext Oauth.txt note
- Added clients/instrumental-music-center/docs/2026-04-13-ticket-notes.md
  (ticket write-up of 2026-04-11/12/13 IMC1 RDS removal/SQL migration work)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-14 21:06:20 -07:00
parent 72105233a2
commit dd5c5afd4b
80 changed files with 13466 additions and 0 deletions

3
clients/dataforth/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# plaintext credential note - never commit
Oauth.txt

View File

@@ -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=<cursor>`. 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.

View File

@@ -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 3050 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** | 24 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** | 23 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** | 610 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)

View File

@@ -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]}")

View File

@@ -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();

View File

@@ -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()

View File

@@ -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()

View File

@@ -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')

View File

@@ -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()

View File

@@ -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']})")

View File

@@ -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()

View File

@@ -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); });

View File

@@ -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()

View File

@@ -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()

View File

@@ -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}')

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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).

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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.

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C

View File

@@ -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).

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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).

View File

@@ -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).

View File

@@ -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).

View File

@@ -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

View File

@@ -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)

View File

@@ -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).

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C

View File

@@ -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).

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmDSfiles = 100, 100, 1126, 472, , 100, 100, 1126, 472, C

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,2 @@
A_Main = 50, 50, 1076, 422, Z
frmSplash = 100, 100, 1126, 472, , 75, 75, 1101, 447, C

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff