We have an application called Job Entry. It takes some of its data from the JobEntryData.csv as shown below.
var csvPath = "C:\\TestData\\JobEntryData.csv"; Driver = DDT.CSVDriver(csvPath); ih.RunInnovationsProgram("JobEntry.exe"); ih.LoginToInnovations("JobEntry","Ocuco",""); while (!Driver.EOF()) { PopulateIDPage(Driver); PopulateFramePage(Driver); PopulateLensesPage(Driver); PopulateRxPage(Driver); PopulateExtrasPage(Driver); //Indexes to next line of data source Driver.Next(); } DDT.CloseDriver(Driver.Name); }
Some of these PopulateXXXXPage() functions are straightforward, but others data will change based on a combo box. In the switch statement below, you can see the FrameSource_xxxxx changes based on a combo box value. Library, Manual, Uncut in this case.
switch (FrameSource) { case "Library" : FrameSource_Library(groupBox); groupBox.ckEdge2.Keys('[Enter]'); break; case "Manual" : FrameSource_Manual(groupBox); groupBox.ckEdge2.Keys('[Enter]'); break; case "Uncut" : FrameSource_Uncut(groupBox); break; }
Which executes a given function, like the FrameSource_Library():
function FrameSource_Library(groupBox) { var csvPath = "C:\\TestData\\FramesPage\\FrameSource_Library.csv"; Driver = DDT.CSVDriver(csvPath); var libraryTracing = Driver.Value(0); var type = Driver.Value(1); var fClass = Driver.Value(2); var dbl = Driver.Value(3); groupBox.cbxSource2.Keys("[Enter]"); groupBox.ISTraceLib2.Keys(libraryTracing + "[Enter]"); groupBox.cbxType2.Keys(type + "[Enter]"); groupBox.cbxClass2.Keys("[Enter]"); }
The problem I'm having is after the original pass and after the driver indexes to the next record. It uses the values from FrameSource_Library.csv and not the JobEntry.csv.
I'm pretty sure it has to do with the value persisting in the driver variable.
Before getting into a solution, is this even a good way to do this? If not, got any suggestions?
I hope this is clearer than mud.
Solved! Go to Solution.
My best guess is this... You have too many CSV connections open. You need to make sure that, when you're finished iterating through a CSV result set, you use DDT.CloseDriver to close the connection. There is a limitation in the database engine for CSV connections that restricts how many connections can be open.
I see, in your code, you have the call... but it's commented out.
Change that line to DDT.CloseDriver(Driver.Name) and that should work. You need to make sure you have the same sort of call for all your DDT drivers so that you're closing the connection when it's no longer needed
You are using the "Driver" variable in two different places... I'm assuming that's declared globally. So, when you change the Driver to point to a different csv, that's replacing the Driver previously declared. You should use a different variable for each driver.
I don't know if this is going to work anyway.
For my various frame data csv's I may only have 4 rows, but in my main job entry csv I could have 50 rows.
What happens when I run out of rows on one csv, but I'm still indexing through the other?
You're not indexing through the second one anyways.... you're just grabbing the first row out of the FrameSource_Library.csv with no loop at all. So, it really doesn't matter.
The key problem to your current code is reusing the "Driver" identifier for two different CSV files. You should have a different identifier for each file so you can keep them distinct.
I know, but I need to index through them as well.
I'm thinking the only way to do this is to create one giant csv with all possible fields and start my while loop with a function MapFields(Driver);
Then every loop, it remaps all my variables to the next row in the document and I use the variables as need be based on logic from the program.
I'd rather have something more modular, but it doesn't seem like I can do that without keeping multiple ddt drivers in sync.
Here's the thing... Let me demonstrate with sample code.
function MyTest(){ var Driver1 = DDT.CSVDriver('C:\\MyFolder\\MyFirstFile.csv') while (!Driver1.EOF()) { DoSomething() Driver1.Next() }
DDT.CloseDriver(Driver1.Name); } functgion DoSomething(){ var Driver2 = DDT.CSVDriver(C:\\MyFolder\\MySecondFile.csv') while (!Driver2.EOF()){ DoSomethingElse() Driver2.Next() }
DDT.CloseDriver(Driver2.Name) }
In the above sample, the number of lines in the two CSVs have no relation to each other. For each record in Driver1, it will loop through all records in Driver2. So, even if they have a different number of records, it doesn't matter.
From what I'm reading (and I may be wrong), this is what you're attempting to achieve. You don't have to worry about the files being in sync, you just need to make sure that the drivers have unique identifiers. That way, you'll always get all rows of both files.
Now, if I'm misunderstanding how you're implementing your second driver, please clarify. As it is, from what I see in your posted code, there is no direct relationship between the values in the first file and the values in the second file, just that you have two files.
Our application has multiple pages.
ID Page (1)
Frame Page (2)
Lens Page (3)
Rx Page (4)
Extras Page (5)
The above pictures are the pages of the application that need input. Now not all pages are static.
For example the Frames Page is set to Library and has certain fields available.
Here's what it looks like if Uncut was selected:
Frames_Uncut
One "trip" through all of these pages is one order.
That order could use different frame sources which would mean different values would have to be used.
So for each job (one pass through all pages) the possilbe input needed will change.
So should I create one big csv with all values, map them to unique global variables and then use them however I need using logic in the test?
Or should I somehow split the value various input field models to their own data sources?
ex.
Library.csv would need:
Type
Class
DBL
Uncut.csv would need
Right horizontal measure
Right Vertical measure
Left horizontal measure
Left Vertical measure
You can do it with multiple CSV files. What I would do is structure the CSV files as you would a relational database. So, you have your primary driver that is going through each order. So, we know that there is some sort of unique ID for that order within the CSV file. So, the first order would be order 1, second 2, third 3, and so forth.
Then, each supporting CSV file would link back to that primary via that order ID. So, you would have that ID as a column in the supporting CSV for Uncut and all the others.
So, when you need to go to that secondary CSV, you would then pass in the OrderID from the first and then filter the SQL.
SQL you say? Yes, SQL... because behind the scenes of the DDT.CSVdriver is an ADO object with a command object and text that indicates what to retrieve. So, if we go back to my original code sample, assuming that orderID is in the first CSV file....
function MyTest(){ var Driver1 = DDT.CSVDriver('C:\\MyFolder\\MyFirstFile.csv') while (!Driver1.EOF()) { DoSomething(Driver1.Value('OrderID')) Driver1.Next() } DDT.CloseDriver(Driver1.Name); } functgion DoSomething(orderID){ var Driver2 = DDT.CSVDriver(C:\\MyFolder\\MySecondFile.csv') Driver2.CommandObject.CommandText = 'SELECT * from MySecondFile.csv where orderID = ''' + OrderID + ''' while (!Driver2.EOF()){ DoSomethingElse() Driver2.Next() } DDT.CloseDriver(Driver2.Name) }
Now, the first driver will loop through all the orders... the second driver will only loop through those records in the second ID file that corresponds to the current order being worked with from the first file.
You would replicate this for every process in that switch statement.
Make sense? Basically, you're treating a set of CSV files as a relational database like an MSSQL database.
Subject | Author | Latest Post |
---|---|---|