Inserting a column from an SQL query into a data column in HPE UFT - sql

This is the code in HPE UFT that successfully runs the query and displays a msg box.
I would like it to store the query results or at least 1 column of the query results in the HPE UFT data table so that I can run a loop on those loan numbers later.
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
objConnection.open "provider=123ABC;Server=T1;User Id=****;
Password=****; Database=i_prod;Trusted_Connection=Yes"
sqlQuery="SELECT Table1 AS LoanNumber, lm.loanrecordid, clm.istexasconversion as TexasConversion FROM Table1 lm WITH (NOLOCK) LEFT JOIN Table2 clm WITH (NOLOCK) ON clm.lenderdatabaseid = lm.lenderdatabaseid AND clm.loanrecordid = lm.loanrecordid Where clm.istexasconversion IS NOT NULL"
objRecordSet.open sqlQuery, objConnection
value = objRecordSet.fields.item(0)
msgbox Value
objRecordSet.Close
objConnection.Close
Set objConnection = Nothing
Set objRecordSet = Nothing
This is the query used in SQL.
SELECT
lm.loanid AS LoanNumber
,Column1
,column2 as Texas
FROM table1 lm WITH (NOLOCK)
LEFT JOIN table2 clm WITH (NOLOCK)
ON clm.lenderdatabaseid = lm.lenderdatabaseid
AND clm.loanrecordid = lm.loanrecordid
Desired Result Image

To start with, it helps if you define the parameter names initially in the table like this:
Datatable.AddParameter("LoanNumber", dtGlobal)
Datatable.AddParameter("LoanID", dtGlobal)
Datatable.AddParameter("TexasConversion", dtGlobal)
This will set the first three columns of the Global datatable with the name of the parameter you are going to insert.
Then, for ease of use, put the data in your RecordSet into an Array:
myArray = objRecordSet.GetRows ' do this before you close the recordset
And finally, loop around the two dimensional array to populate the table with data:
For myLoop = 0 to UBound(myArray, 2) ' loop over the total rows
DataTable.SetCurrentRow(myLoop + 1) ' +1 as row count starts from 1 not 0
Datatable("LoanNumber") = myArray(0, myLoop)
Datatable("LoanID") = myArray(1, myLoop)
Datatable("TexasConversion") = myArray(2, myLoop)
Next
And if you need to store a copy of the datatable (unless you plan to only use this data during the run, you will need to):
Datatable.Export("\\Path\To\File\To\Save.xlsx")
If you have any trouble following this, post a comment and I'll try to explain further.

You can use database output values to output the values from your column.
Steps to create database output values:
Select Insert> Output Values> Database Output Values
Create connection string
Choose in Query definition 'Specify SQL statement manually' radio button and maximum number of rows
In Sql statement edit field insert your query

Related

select in select sql query

I want to create a sql query. The column name that I want, it's in another table. I wrote this query.
SELECT (SELECT FieldName From TableGENQuest WHERE ID = 1)
FROM TableGEN
WHERE strSO = 'RV12648-01';
I want to get the data from the strGEN1 columns using the FieldName column of the TableGENQuest table.That is data I want No significant transportation damage observed.
tl;dr: Your request is not possible using MS Access SQL alone.
You will need to use VBA to open a recordset containing the content of the table TableGENQuest and construct an appropriate SQL statement whilst iterating over the records held by such recordset.
For example:
Sub GenerateQuery()
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim sql As String
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("SELECT FieldName FROM TableGENQuest WHERE ID = 1")
With rst
If Not .EOF Then
.MoveFirst
Do Until .EOF
sql = sql & "[" & !FieldName & "], "
.MoveNext
Loop
sql = "select " & Left(sql, Len(sql) - 2) & " from TableGEN WHERE strSO = 'RV12648-01';"
End If
.Close
End With
If sql <> vbNullString Then dbs.CreateQueryDef "OutputQuery", sql
Set rst = Nothing
Set dbs = Nothing
End Sub
The above will generate a query defined in the current database with a SQL statement selecting the fields whose fieldnames are sourced using the SQL:
SELECT FieldName FROM TableGENQuest WHERE ID = 1
The difficulty and convoluted nature of this method indicates that your database is poorly designed: the field names themselves should instead appear as rows within another table.
SELECT b.FieldName FROM TableGEN a
LEFT OUTER JOIN TableGENQuest b
ON a.ID=b.ID
WHERE a.strSO = 'RV12648-01'
AND b.ID=1
OR
SELECT a.strSO,b.FieldName,b.ID
FROM TableGEN a
LEFT OUTER JOIN
(
SELECT FieldName,ID From TableGENQuest WHERE ID = 1
)
b
ON a.ID = b.ID
WHERE strSO = 'RV12648-01'
Try This Query...or can change Join Type...
Try this:
SELECT TableGENQuest.FieldName
FROM TableGEN, TableGENQuest
WHERE TableGENQuest.ID=1 AND WHERE strSO = 'RV12648-01';

loop through records and add record or create if none exists to new table depending on multiple criteria

I'm new to access/vba and trying to set up a project database. I have a table ("Updates") that is generated when changes are made to certain fields on a form (used for project updates by the end user). It has the primary key UpdateID, foreign key ProjectID as well as UTimeStamp, OldValue, NewValue, History. I use the history key to identify which type of update was made (for example for Status, History=1). I want to then count the number of projects for each status at the end of each month, keeping historical data to allow users to track the changes from month to month (or even compare data from months apart). I'm trying to write a code (in VBA for access) that would take into account that there are sometimes multiple status updates in each month and I don't want them to get counted twice, also some months no updates are made but I still want them included in the count (using the last updated status before that month as the status).
I was thinking of using a combination of looping through the records and checking to see if a value exists for that specific ProjectID and month and inserting the last value (most recent) into a new table "StatusTracking" and if no record exists then using the INSERT INTO function to add a new record. "StatusTracking" will have the fields ID, ValueMonth, ValueYear, (since ideally I want to track over the course of more than a year) Status, ProjectID. However, I am very new to this and am having trouble getting started as I'm not sure the best way to loop through both the months and ProjectID.
Public Function getStatus()
Dim varMonth As Integer
Dim ReportStatus As String
Dim RS As DAO.Recordset
Dim db As DAO.Database
Dim sqlStr As String
sqlStr = "SELECT Updates.ProjectID, Format(Month([UTimeStamp])) AS UpdateMonth, ProjectList.Status, Updates.NewValue, Updates.UTimeStamp" & _
"FROM Updates RIGHT JOIN ProjectList ON Updates.ProjectID = ProjectList.ProjectID" & _
"WHERE (((Updates.History) = 1))" & _
"GROUP BY Updates.ProjectID, Format(Month([UTimeStamp])), ProjectList.Status, Updates.NewValue, Updates.UTimeStamp"
Set db = CurrentDb
Set RS = db.OpenRecordset(sqlStr)
With RS
.MoveLast
.MoveFirst
While (Not .EOF)
'Cycle through each month
For varMonth = 1 To 12 Step 1
ReportStatus = DLast("NewValue", RS, "UpdateMonth = " & varMonth)
RS.Fields ("Status") <> RS.Fields("NewValue")
End Function
Any help is appreciated!
DCount is useful for counting unique occurrences in a specified field. The link I provided should put you on the right track there. Note that that only returns the count itself, and not the records. If you need to populate a recordset, you can use SELECT DISTINCT in your query to return only the records that have, well, distinct values in your criteria.
I recently worked on a project that involved building a history table for tracking purposes. Since it was based around forms, I opted for using .addnew and .update rather than INSERT INTO. Of course, use what's best for the situation at hand; I used .addnew and .update for the main reason that I had a lot of controls in my form and it was simpler in my mind to do it that way. There's lots of ways to do it, this worked best for me. I've also provided a snippet of the code I wrote for that project as another example.
Hope this helps!
'Example
'Assuming recordset and database variables are already declared
'rec = recordset, db = currentdb
set rec = db.openrecordset(<source table, name of existing query, or SQL query>)
if <condition is met> then
'populate table with values in form controls
rec.addnew
rec("Destination Table Field") = Me.Controls("Name of Form Control").Value
.
.
.
rec.update
set rec = nothing
set db = nothing
'clearing rec and db after done using
end if
Code from my project:
Set db = CurrentDb
Set rec = db.OpenRecordset("Select * from tbl_maintenanceOrders")
Set recHist = db.OpenRecordset("Select * from tbl_umoHistory")
msgConfirm = MsgBox("Correct values confirmed?", vbYesNo, "Continue")
'enter record in maintenance order table
If msgConfirm = vbYes Then
rec.AddNew
recHist.AddNew
rec("openTimestamp") = Now()
rec("openedBy") = Me.Controls("cbo_originator").Value
rec("assetID") = Me.Controls("cbo_asset").Value
rec("assetDesc") = Me.Controls("txt_assetDesc").Value
rec("priority") = Me.Controls("cbo_priority").Value
rec("umoProblemDesc") = Me.Controls("txt_issueDesc").Value
rec("umoSpecifics") = Me.Controls("txt_issueDetails").Value
rec("umoState") = "open"
rec("umoStatus") = "new"
rec.Update
'add UMO history entry
recHist("umoID") = rec("orderID")
recHist("activity") = "opened"
recHist("umoState") = "open"
recHist("umoStatus") = "new"
recHist("activityDesc") = "UMO Requested"
recHist("initiatorID") = Me.Controls("cbo_originator").Value
recHist("timeStamp") = Now()
recHist("updater") = Me.Controls("cbo_originator").Value
recHist.Update
End If
'cleanup
Set rec = Nothing
Set recHist = Nothing
Set db = Nothing

Update Based on Select

I am attempting to update one column of a table based on data present in other records of the same table. All records either have the same date in the "CurrentDate" field or are null. I want to change those with null values to be the same as the rest of the fields.
Here is my code, but I am getting a syntax error:
Public Sub RiskVisual()
Dim db As DAO.Database
Set db = CurrentDb
---
DoCmd.RunSQL "UPDATE Hold3 SET CurrentDate = (SELECT CurrentDate FROM Hold3 LIMIT 1) WHERE CurrentDate IS NULL;"
End Sub
Thanks in advance for your help.
In MS Access the "TOP 1" works better than "LIMIT 1". You will also want to specify when seeking for the top 1 that the top 1 that is not null. Try something like this:
UPDATE Hold3 SET Hold3.CurrentDate = (SELECT TOP 1 Hold3.CurrentDate FROM Hold3 WHERE (((Hold3.CurrentDate) Is Not Null))) WHERE (((Hold3.CurrentDate) Is Null));

Access SQL How to select randomly a group of contiguous rows

can this be done, say I have rows (1,2,3,4,5) and I want to grab three rows, select one randomly and then get it's neighbors, so maybe the random selection is row (3), I can also grab (2,4) if I wanted its neighbors, do I just pick one at random and then look for the unique key before and after like this or can I do it all in one sql statement.
I was going to use ADO from excel to pull records (so VBA connects to access, opens a recordset with sql instructions and so on).
Hope I was clear!
I would love to just do this all in a SQL statement
I am not sure Access is capable of all the SQL commands such as SQL Server, so this may be a bit of a problem. If you have a primary key though, you can easly generate a Select query in VBA and then pass open recordset with this SQL.
Dim sSQL as String
Dim lRand as Long
Dim rs as ADODB.Recordset 'or DAO.Recordset'
lRand = VBA.Int(VBA.Rnd() * TableRecordCount) ' TableRecordCount is the number of records in the table that you need to get somehow'
sSQL = "SELECT * FROM TableName WHERE (ID>=" & lRand - 1 & " AND ID <=" & lRand + 1
set rs = CurrentDB.OpenRecordset(sSQL, ...)
I am now not absolutely sure of what you want to use and depending on ADODB or DAO choice, you need to open the recordset accordingly with wither Call rs.Open or Set rs = DB.OpenRecordset

Query creating an identifier for each packet

Sorry the title is not very descriptive but it is a tricky problem to word.
I have some data, about 200 or more rows of it, and each row has a PacketID, so several rows belong in the same packet. What I need to do, is convert all the PacketIDs from (Example - BDFD-2) to just a number (Example - 1) so all the entries with a packet identifier x need to have a packet identifier of say 3. Is there an SQL query that can do this? Or do I just have to go through manually.
You asked about a query. I wrote a quick VBA procedure instead just because it was so easy. But I'm unsure whether it is appropriate for your situation.
I created tblPackets with a numeric column for new_PacketID. I hoped that will make it clearer to see what's going on. If you truly need to replace PacketID with the new number, you can alter the procedure to store CStr(lngPacketID) to that text field. So this is the sample data I started with:
PacketID new_PacketID packet_data
BDFD-2 a
R2D2-22 aa
BDFD-2 b
R2D2-22 bb
EMC2-0 aaa
EMC2-0 bbb
And this is the table after running the procedure.
PacketID new_PacketID packet_data
BDFD-2 1 a
R2D2-22 3 aa
BDFD-2 1 b
R2D2-22 3 bb
EMC2-0 2 aaa
EMC2-0 2 bbb
And the code ...
Public Sub RenumberPacketIDs()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim lngPacketID As Long
Dim strLastPacketID As String
Dim strSql As String
strSql = "SELECT PacketID, new_PacketID" & vbCrLf & _
"FROM tblPackets" & vbCrLf & _
"ORDER BY PacketID;"
Set db = CurrentDb
Set rs = db.OpenRecordset(strSql)
With rs
Do While Not .EOF
If !PacketID <> strLastPacketID Then
lngPacketID = lngPacketID + 1
strLastPacketID = !PacketID
End If
.Edit
!new_PacketID = lngPacketID
.Update
.MoveNext
Loop
.Close
End With
Set rs = Nothing
Set db = Nothing
End Sub
I think an approach like that could be fine for a one-time conversion. However if this is an operation you need to perform repeatedly, it could be more complicated ... especially if you need each PacketID replaced with the same number from one run to the next ... eg. BDFD-2 was replaced by 1 the first time, so must be replaced by 1 every time you run the procedure.
If you only have a few packet IDs, you can just use update:
UPDATE table_name
SET PacketID =
(
CASE PacketID
WHEN 'BDFD-2' THEN 3
WHEN 'ABCD-1' THEN 5
ELSE 2
END
)
The ELSE is optional.
I am not sure why you even want to convert the packet ids to a number, they seem perfectly fine as they are. You could create a table of packets as follows
SELECT DISTINCT TableOfRows.Packet_id AS PacketId INTO Packets FROM TableOfRows;
You can then use this to select the packet you are interested in and display the corresponding rows