Sign in to follow this  
Followers 0
makeinstall

Possible LOOP error - all data from loop being written into all files

6 posts in this topic

I am trying to create several CSV files for multi function devices that hold address book data of several hundred users. Each device requires its own information on the first 5 lines of the file so to cut down on my time, I am trying to create it dynamically whilst only maintaining one master address book.

At the top of each CSV file, something like the following should be created:

#Registration Data,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

#Format Version:3.1.5.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

#Export Date: 17/03/2010 11:57:01,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

#Device Name: Rxxxxxx,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

#Address: 10.162.xxx.xxx,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

But this data for ALL of the machines is being placed at the top of every CSV file created for each device. I can't help but think it's a silly schoolboy error that I'm too snow blind to see.

Any help/advice is greatly appreciated.

The script is as follows:

;############################################################################
;   INCLUDES
#NoTrayIcon
#include <Array.au3>
#Include <Misc.au3>
#include <File.au3>
#include <GUIListBox.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <ListboxConstants.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>



;############################################################################
;#  Prevents 2 scripts running
_Singleton(@ScriptName)

;############################################################################
;   CONSTANTS

;   LOCATIONS OF FILES
;   Master CSV location
Dim Const $masterCSV = "\\PATH\TO\FOLDER\MasterList.csv"
Dim Const $CSVfolder = "\\PATH\TO\FOLDER\MachineCSV\"

; CSV FILE CONSTANTS
; closing commas that fill out the rest of the empty fields
Dim Const  $closingCommas = ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
;   Constant for first 5 lines of csv data
Dim Const $leadingData = "#Registration Data" & $closingCommas & @CRLF & "#Format Version:3.1.5.0" & $closingCommas & @CRLF & "#Export Date: "

; Declare other vars
Dim $device

; GUI Declarations
Dim $hGUI, $hList, $hButton


;############################################################################
;   Machine Reg Data
; Sets up constants with the first 4 lines of data required by the CSV file, as unique machine ID

; MACHINE HOSTNAME ARRAY
; If machine list changes, alter this list and the number in the array
Global $hostname [13]

$hostname[0] = "RNPC210BD"
$hostname[1] = "RNPC1F5B9"
$hostname[2] = "RNPC210AB"
$hostname[3] = "RNPC1F447"
$hostname[4] = "RNPC1F361"
$hostname[5] = "RNPBCE85A"
$hostname[6] = "RNPC20FCF"
$hostname[7] = "RNP9C1AF6"
$hostname[8] = "RNPC1E336"
$hostname[9] = "RNPC21A78"
$hostname[10] = "RNPFD5270"
$hostname[11] = "RNPE0E9C8"
$hostname[12] = "RNPB9762D"




;############################################################################
;   PROCESS
; Creates GUI for user feedback
_CreateGUI()

GUICtrlSetData($hList, "This will now create the address book for each |of the following MFD devices:||")

; start TCP services
TCPStartup()
 

For $device in $hostname
    ; resolve hostname to IP address
    $machineIP = TCPNameToIP($device)
    ; create copy of masterCSV file & name it $hostname.csv
    ;_copyCSV($masterCSV, $CSVfolder, $device)
    
    ; Compile export date with trailing commas
    $date = @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR  & ":" & @MIN & ":" & @SEC & $closingCommas & @CRLF
    
    ; Build vars for hostname & IP address
    $hostData = "#Device Name: " & $device & $closingCommas & @CRLF & "#Address: " & $machineIP & $closingCommas
    
    ; Compile all 5 lines of data in one string
    $machineData = $leadingData & $date & $hostData
    
    ; Write to file: line 1
    _writeMachineData($machineData)
    
    ;console/GUI display
    GUICtrlSetData($hList, $device &"|")
    
Next
GUICtrlSetData($hList, "..............|")
;   GUICtrlSetData($hList, "")
GUICtrlSetData($hList, "The script has now completed successfully |and will close in 5 seconds.")
Sleep(5000)
Exit

;GUI polling
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

;############################################################################
;   FUNCTIONS

; function copies the master csv file and names the copy to the device hostname
Func _copyCSV($masterCSV, $CSVfolder, $device)
    ; Declarations
    local $fileCopy
    
    ; Copy masterCSV
    $fileCopy = FileCopy($masterCSV, $CSVfolder & "\" & $device & ".csv")
    
    if $fileCopy = @error Then
        ; create GUI msg that it didnt work
    Else
        ; GUI msg confirms
    EndIf
EndFunc


; FUNCTION to write line to file 
Func _writeMachineData($machineData)
    
    $csvPath = $CSVfolder & "\" & $device & ".csv"
    $writeData = _FileWriteToLine($csvPath, 1, $machineData, 0)
    
    If $writeData = @error Then
        ; GUI Update with error message
        ;GUICtrlSetData($hList, "Checking U drive exists.....|")
    Else
        ; GUI Update that its complete
    EndIf
EndFunc

; GUI Creation
Func _CreateGUI()
    $hGUI = GUICreate("MFD Address book duplicator", 320, 350, 396, 210)
    $hList = GUICtrlCreateList("", 5, 57, 308, 280, BitOR($WS_VSCROLL, $LBS_NOSEL))
    GUICtrlSetData(-1, "Welcome.....|")
    $Label1 = GUICtrlCreateLabel("MFD Address book", 58, 15, 257, 30)
    GUICtrlSetFont(-1, 14, 400, 0, "Verdana")
    GUISetState(@SW_SHOW)
EndFunc   ;==>_CreateGUI

Share this post


Link to post
Share on other sites



You have a hard-coded trailing backslash in the $CSVFolder declaration, but then append another one onto it in both _copyCSV() and _writeMachineData().

Other than that, the logic appears sound.

What does a sample of your output look like?

Share this post


Link to post
Share on other sites

Thanks for the reply. I've adjusted the trailing slash - well spotted!

The output of all the CSV's looks like this (with the first couple of entries obfuscated obviously):

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:32:51

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:32:32

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:31:47

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:24:59

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:24:39

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:23:42

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:16:04

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:14:53

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:14:34

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:14:00

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:13:28

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:12:48

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:12:11

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:10:18

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration Data

#Format Version:3.1.5.0

#Export Date: 08/03/2010 12:09:27

#Device Name: RNPB9762D

#Address: 10.162.217.65

#Registration No. Type Name Key Display Index Freq. Title 1 Title 2 Title 3 E-mail Address Use Name as Protect Sender Password User Code/Device Login User Name Groups User Belongs to Fax Destination Line Type International Transmission Mode Fax Header Label Insertion 1st Line (Selection) Label Insertion 2nd Line (String) Label Insertion 3rd Line (Standard Message) Protect Folder Password Encoding Protocol Port No. Server Name Path User Name Japanese Character Code Access Privilege to User Access Privilege to Protected Files IP-Fax Protocol IP-Fax Destination Login Password for Device Password Method SMTP Authentication SMTP Authentication: Login User Name SMTP Authentication: Login Password Password Method Folder Authentication Folder Authentication: Login Password Password Method LDAP Authentication LDAP Authentication: Login User Name LDAP Authentication: Login Password Password Method Direct SMTP

<index> <type> <name> <displayName> <phoneticName> <common> <tagSet1> <tagSet2> <tagSet3> <address> <isSender> <protect> <password> <userCode> <group> <faxNumber> <lineType> <isAbroad> <ttiNo> <label1> <label2String> <messageNo> <protectFolder> <passwordEncoding> <folderProtocol> <ftpPort> <folderServer> <folderPath> <folderUser> <ftpCharCoding> <entryACL> <documentACL> <IPfaxProtocol> <IPfaxAddress> <authPassword> <passwordEncoding2> <SMTPAuth> <SMTPUser> <SMTPPassword> <passwordEncoding3> <folderAuth> <folderPassword> <passwordEncoding4> <LDAPAuth> <LDAPUser> <LDAPPassword> <passwordEncoding5> <DirectSMTP>

[00001] [A] [Axxxx, D] [Axxxx, D] [0] [1] [0] [0] [dxxxx.axxxx@xxxxxx.xxx] [0] [0] [] [] [] [] [0] [0] [1] [0] [] [0] [0] [] [0] [] [] [] [] [] [0] [] [0] [] [] [] [0] [] [] [0] [] [] [] [0]

[00002] [A] [Axxxx, U] [Axxxx, U] [0] [1] [0] [0] [uxxx.axxx@xxxxxx.xxx] [0] [0] [] [] [] [] [0] [0] [1] [0] [] [0] [0] [] [0] [] [] [] [] [] [0] [] [0] [] [] [] [0] [] [] [0] [] [] [] [0]

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thanks for the reply. I've adjusted the trailing slash - well spotted!

The output of all the CSV's looks like this (with the first couple of entries obfuscated obviously):

Odd...

I chopped up your code and ran it on my machine.

I did take a few liberties, I thought it might reduce disk I/O's and network traffic if the master file were only accessed a single time. Do you get the same duplicated results with something like this?

;############################################################################
;   INCLUDES
#NoTrayIcon
#include <Array.au3>
#Include <Misc.au3>
#include <File.au3>
#include <WindowsConstants.au3>
#include <ListboxConstants.au3>

;############################################################################
;#  Prevents 2 scripts running
_Singleton(@ScriptName)

;############################################################################
;   CONSTANTS

Dim Const $MasterCSV = "C:\XXX\MasterList.csv"
Dim Const $CSVfolder = "C:\XXX\"

Global $hostname [3]
$hostname[0] = "SCREAMER"
$hostname[1] = "ASHLEY"
$hostname[2] = "RAPTOR"

Dim $MasterArray
Dim $DeviceArray[5]
Dim Const  $closingCommas = ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
$DeviceArray[0] = "#Registration Data" & $closingCommas
$DeviceArray[1] = "#Format Version:3.1.5.0" & $closingCommas
$DeviceArray[2] = "#Export Date: " & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR  & ":" & @MIN & ":" & @SEC & $closingCommas

Dim $hGUI, $hList, $hButton


;############################################################################
;   PROCESS

; Load Master CSV to Array
If Not _FileReadToArray($MasterCSV,$MasterArray) Then
   MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
   Exit
EndIf
; Append Master Array to Device Array
_ArrayConcatenate($DeviceArray, $MasterArray, 1)

_CreateGUI()
_Process_Devices()
Exit
;############################################################################
;   FUNCTIONS

Func _CreateGUI()
    $hGUI = GUICreate("MFD Address book duplicator", 320, 350, 396, 210)
    $hList = GUICtrlCreateList("", 5, 57, 308, 280, BitOR($WS_VSCROLL, $LBS_NOSEL))
    GUICtrlSetData(-1, "Welcome.....|")
    $Label1 = GUICtrlCreateLabel("MFD Address book", 58, 15, 257, 30)
    GUICtrlSetFont(-1, 14, 400, 0, "Verdana")
    GUISetState(@SW_SHOW)
    GUICtrlSetData($hList, "Creating an address book for the following MFD devices:||")
EndFunc   ;==>_CreateGUI

Func _Process_Devices()
    Local $device
    ; start TCP services
    TCPStartup()
    For $device in $hostname
        ; resolve hostname to IP address
        $machineIP = TCPNameToIP($device)
        ; Build vars for hostname & IP address
        $DeviceArray[3] = "#Device Name: " & $device & $closingCommas
        $DeviceArray[4] = "#Address: " & $machineIP & $closingCommas
        ;_ArrayDisplay($DeviceArray) ; for testing
        ; Write DeviceArray to File
        If Not _FileWriteFromArray($CSVfolder & $device & ".csv", $DeviceArray) Then
            MsgBox(4096,"Error", " Error write Array to file     error:" & @error)
            ;GUICtrlSetData($hList, "Checking U drive exists.....|")
            Exit
        EndIf
        ;console/GUI display
        GUICtrlSetData($hList, $device &"|")
    Next
    ; shutdown TCP services
    TCPShutdown()

    GUICtrlSetData($hList, "..............|")
    GUICtrlSetData($hList, "The script has completed successfully |and will close in 5 seconds.")
    Sleep(5000)
EndFunc

I might make a text or ini file with your version number as the first line, and your list of hostnames following. Reading that into a $version variable and the $Hostname{} array would make future changes cake.

Edit: Oops, I'd chopped that _FileWriteFromArray out of an existing script and didn't remove the i_base parm that told it not to copy the first element of the array. Code corrected (also added TCPShutdown).

Edited by Spiff59

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thanks for your help. The way you have approached the code intrigues me as I think I'm far too linear.

I've changed the file locations and the array of hostnames but I get this error from your code:

U:\AutoIT scripts\MFD_AddressBook.au3(56,48) : ERROR: _ArrayConcatenate() called with wrong number of args.

_ArrayConcatenate($DeviceArray, $MasterArray, 1)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

C:\Program Files\AutoIt3\Include\Array.au3(200,73) : REF: definition of _ArrayConcatenate().

Func _ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

U:\AutoIT scripts\MFD_AddressBook.au3 - 1 error(s), 0 warning(s)

Edited by makeinstall

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

The third parm for _ArrayConcatenate was added in Autoit version 3.3.1.2.

You ought to install the latest version: 3.3.6.0

Edit: You could also combine the arrays manually with like 6 lines of code:

; Get length of first array
$Len1 = UBound($DeviceArray) ; 0-based array, so no adjustment
; Get length of second array
$Len2 = $MasterArray[0] - 1 ; 1-based array, so adjust size to ignore first 'count' element
; Expand first array
ReDim $DeviceArray[$Len1 + $Len2]
; Loop through and copy elements from second array to first array (beginning at offset $Len1)
For $x = 1 to $Len2 ; Leave off the second array count element by starting at 1 instead of 0
    $DeviceArray[$Len1 + $x - 1] = $MasterArray[$x] 
Next

The actual _ArrayConcatenate function in the array.au3 UDF is likely 2 to 3 times larger due to parameter editing and error handling (I suppose I could just go look at in in like 10 seconds lol).

Edited by Spiff59

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0