I am updating an old VBScript. I was trying to add two variables together in a VBScript function I'm working on, one is a negative while the other is a positive but when the number gets sent back to the SQL table it doesn't calculate correctly. I have code that is similar to this that function correctly when you subtract
EX:-76+4 ends up being -80 instead of -72.
here is code maybe something is wrong with variable.
strSQL = "UPDATE Parts SET On_Hand = '"
strSQL = strSQL & (CInt(objRS("On_Hand")) + CInt(Request.Form("QtyIssued"))) & "'"
strSQL = strSQL & "WHERE Part_ID = '" & Request.Form("PartNum" & x) & "';"
Note: I have change Cint from Ccur and still didn't work.
On_Hand is also a float in the table.
EDIT: Added full code for clarity
strSQL = "UPDATE Parts SET On_Hand = '"
strSQL = strSQL & (CInt(objRS("On_Hand")) + CInt(Request.Form("QtyIssued"))) & "'"
strSQL = strSQL & "WHERE Part_ID = '" & Request.Form("PartNum" & x) & "';"
Response.Write strSQL & "<br>"
objRS.close
objRS.Open strSQL, objConn
Here is Response Write:
UPDATE Parts SET On_Hand = '-80'WHERE Part_ID = '15-0219';
You need to check your input values coming from the form, as a simple test can debunk your theory that the calculation is wrong.
<%
Dim sum
Dim x, y
x = -76
y = 4
sum = x + y
Call Response.Write(sum)
Call Response.Write("<br />")
x = "-76"
y = "4"
sum = CInt(x) + CInt(y)
Call Response.Write(sum)
%>
Output:
-72
-72
Related
I have a table in Access with the relevant fields EFTRecID, EFTRecIDNum and CreatedBy. EFTRecIDNum is an auto number field, and EFTRecID concatenates the required format of "CE" & EFTRedIDNum. I am attempting to return the highest value in the EFTRecID field that was created by the current user. To do this I am trying to do a sub query that finds the Max(EFTRecIDNum) WHERE Created = my name. However instead of returning the max, it is returning all values with my name. I know I could use the format option to just format the EFTRecIDNum field, but I need to be able to search in the format CE456.
TL;DR: Query returns all records with my name, rather then max with my name.
Public Sub DownloadMyRecords()
Dim intI As Integer 'Used for looping in a variety of locations
strSQL = "SELECT EFTRecID FROM tblEFTRec WHERE (SELECT MAX(EFTRecIDNum) FROM tblEFTRec WHERE CreatedBy = '" & Application.UserName & "')"
Set cnn = New ADODB.Connection
With cnn
.Provider = "Microsoft.ACE.OLEDB.12.0;Data Source=" & dbLocation & "\" & dbName & ";Jet OLEDB:Database Password=" & DBPWord
.Open dbLocation & "\" & dbName
End With
Debug.Print strSQL
Set rst = New ADODB.Recordset
rst.CursorLocation = adUseServer
rst.Open Source:=strSQL, ActiveConnection:=cnn, _
CursorType:=adOpenForwardOnly, LockType:=adLockOptimistic, _
Options:=adCmdText
Debug.Print (rst.GetString)
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
End Sub
Try this SQL statement instead:
strSQL = "SELECT EFTRecID
FROM tblEFTRec
WHERE EFTRecIDNum = (SELECT MAX(EFTRecIDNum) FROM tblEFTRec WHERE CreatedBy = '" & Application.UserName & "')"
Try using:
"SELECT EFTRecID FROM tblEFTRec
WHERE EFTRecIDNum = (SELECT MAX(EFTRecIDNum) FROM tblEFTRec
WHERE CreatedBy = '" & Application.UserName & "')"
Is there a reason the following doesn't work?
"SELECT MAX(EFTRecID) FROM tblEFTRec
WHERE CreatedBy = '" & Application.UserName & "'"
I am working on an Access 2007 database and I have set up a DAO recordset query, however, it is not returning any results. It does not throw up any errors, just no results. Me.ProID is a text field, it includes letters and numbers. I think it has something to do with the text field, maybe the placement of quotations.
Dim contractSQL As String
Dim contractDB As DAO.Database
Dim contractRS As DAO.Recordset
contractSQL = "SELECT Top 1 ContractName, ItemDescription, Price FROM ContractPricing WHERE AccountNo = " & Me.Parent.[AccntNumber] & " AND PartNo = " & """ & Me.ProdID & """ & " ORDER BY Price Asc"
Set contractDB = CurrentDb
Set contractRS = contractDB.OpenRecordset(contractSQL)
Debug.Print contractRS.RecordCount
That string concatenation is likely wrong. " & """ & Me.ProdID & """ & " should almost certainly be '" & Me.ProdID & "'
I don't know if you're referring to this:
contractSQL = "SELECT Top 1 ContractName, ItemDescription, Price FROM ContractPricing WHERE AccountNo = " & Me.Parent.[AccntNumber] & " AND PartNo = " & Me.ProdID & " ORDER BY Price Asc"
I'm not sure if this would help you. I'm also new to this. But hopefully it will.
I have 8 combo boxes in an Access database. Each combo box can either have a value or not have a value (2 options). In total, there can be 256 combinations (2^8). I am trying to create some code in VBA that loops through these combinations to determine which combination currently exists, with the ultimate goal of writing an SQL query within VBA based on that combination. So for example, let's say combo1 and combo2 both have selections, but not combo3 through combo8. If that is the combination I would like my SQL query to do a SELECT FROM query WHERE a column in db = combo1 and a column in db = combo2. Can anyone provide hints as to how I would structure my code?
Thanks!
Dim a as string, b as string
const myAND as string = "AND "
a = ""
a = "SELECT * FROM a table "
b = ""
if cbo1.value <> "" then
b = b & myAND & "AND field1 = '" & cbo1.value & "'"
end if
if cbo2.value <> "" then
b = b & myAND & "field2 = '" & cbo2.value & "'"
end if
etc for each cbo box
If b <> "" Then
' Lazy way
' a = a & "WHERE 1=1 " & b
' remove the first AND way
a = a & "WHERE 1=1 " & mid(b,len(myAND))
End if
' a now contains the SQL you need.
Dim where_condtion as String
Dim sqlquery as String
where_condtion = ""
IF combo1 <>"" then
where_condtion = where_condtion + "~fieldname~ = " & combo1
End IF
IF combo2 <>"" then
where_condtion = where_condtion + "AND ~fieldname~ = " & combo2
End IF
*
*
*
IF combo8 <>"" then
where_condtion = where_condtion + "AND ~fieldname~ =" & combo8
End IF
IF where_condtion <> "" then
sqlquery = "Select * from ~table name~ where" + where_condtion
ELSE
sqlquery = "Select * from ~table name~
End IF
sqlquery = Replace(sqlquery, "where AND ", "where ")
DoCmd.OpenQuery "sqlquery", acViewNormal, acEdit
OR
CurrentDb.OpenRecordset("sqlquery")
Am option would be a concatenated string
Code Example
Dim strSQL as String
'basic string
strSQL = "SELECT tbl.fieldA, tbl.fieldB FROM tbl "
Dim strSQLwhere as String
strSQLwhere = ""
'Combobox cmbbox1
If Not isNull(cmbbox1) And cmbbox1.ListIndex <> -1 then
strSQLwhere = strSQLwhere & "tbl.fieldToFilter1=" & cmbbox1
End if
'Combobox cmbbox2
If Not isNull(cmbbox2) And cmbbox2.ListIndex <> -1 then
iF NOT strSQLwhere = "" then
strSQLwhere = strSQLwhere & " AND "
end if
strSQLwhere = strSQLwhere & "tbl.fieldToFilter2=" & cmbbox2
End if
'And so on until cmbBox 8
'Combine all Strings
if not strSQLwhere = "" then
strSQL = strSQL & " WHERE (" & strSQLwhere & ")"
End if
'Add here further thing like ORDER BY, GROUP BY
'Show SQL sting if it is well fomratted, change string concatenation if not
debug.print strSQL
You could do the combobox if-then-(else) cases in a separate function if you are able to do that in VBA.
I have an expenditures subform in Access 2010 that lists the predicted costs associated with the project for each year. Most projects only have one year, but some have more than one. Each cost has a Final checkbox next to it that should be checked when the amount is confirmed, ie. at the end of each year.
It basically looks something like this:
Year | Cost | Final
--------+-----------+--------------------
2017 | $100 | [checked box]
2018 | $200 | [unchecked box]
| | [unchecked box]
I have another field outside the table, FinalCost, that adds up everything in the Cost field. Right now, it fills in the amount from any year which has a checked Final box. That should only be filled when all the Final boxes are checked.
Ex. Right now, it should show nothing even though Final for 2017 is checked. When 2018 is checked, it should show $300. Instead, it shows $100 even though there's still an empty checkbox.
This is the code for this form.
Private Sub Form_AfterUpdate()
Dim rs1, rs2 As Recordset
Dim sql, sql2 As String
sql = "SELECT Sum(Amount) as Final From Expenditures " & _
"Where ProjNo = '" + Me.ProjNo + "' And Final = True Group by ProjNo"
sql2 = "SELECT FinalExpenditure From ActivityCash " & _
"Where ProjNo = '" + Me.ProjNo + "'"
Set rs1 = CurrentDb.OpenRecordset(sql, dbOpenDynaset, dpinconsistent)
Set rs2 = CurrentDb.OpenRecordset(sql2, dbOpenDynaset, dpinconsistent)
If rs1.RecordCount > 0 Then
If rs2.RecordCount > 0 Then
Do While Not rs2.EOF
rs2.Edit
rs2!FinalExpenditure = rs1!Final
rs2.Update
rs2.MoveNext
Loop
End If
End If
rs2.Close
rs1.Close
Set rs1 = Nothing
Set rs2 = Nothing
End Sub
What would be the best way to go about doing this?
EDIT: When the last box is checked, a new row is automatically added with an untoggled checkbox but no information.
Replace the statement beginning with sql = ... with this:
sql = "SELECT SUM(e1.Amount) AS Final " & _
" FROM Expenditures AS e1 " & _
" WHERE NOT EXISTS (SELECT 'x' FROM Expenditures e2 WHERE e2.Final=0 AND e1.ProjNo = e2.ProjNo) " & _
" AND e1.ProjNo = '" & Me.ProjNo & "'"
This query will return data only if there are all expeditures for the project marked as final. As you check for rs1.RecordCount > 0 there will be no update if this query returns no records.
So, before sql, I would verify that all records have True in your Final field.
To do that, let's just return a COUNT() of (any) records that have Final = False, and we can then decide to do what we want.
So, something like,
Dim Test as Integer
test = DCount("*", "YourTableName", "Final = False AND ProjNo = " & Me.ProjNo &"")
If test > 0 Then
'Don't fill the box
Else
'Fill the box, everything is True
'Read through your recordsets or whatever else you need to do
End If
To use a query, we essentially need to replicate the Dcount() functionality.
To do this, we need another Recordset variable, and we need to check the value of the Count() field from our query.
Create a query that mimicks this:
SELECT COUNT(*) As CountTest
FROM YourTable
HAVING Final = False
AND ProjNo = whateverprojectnumberyou'reusing
Save it, and remember that query's name.
Much like the DCount(), we need to make this "check" determine the route of your code.
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("YourQuery'sNameHere")
If rst!CountTest > 0 Then
'They are not all Checked (aka True)
Else
'Supply the value to the FinalCost
End If
Set rst = Nothing
Change this:
sql = "SELECT Sum(Amount) as Final From Expenditures " & _
"Where ProjNo = '" + Me.ProjNo + "' And Final = True Group by ProjNo"
For this:
"SELECT SUM(Amount) - SUM(IIF(Final,1,0)*Amount) as YetToConfirm, SUM(Amount) as Confirmed From Expenditures " & _
"Where ProjNo = '" + Me.ProjNo + "' Group by ProjNo"
rs1 will return two values, the total value if all costs were confirmed in the rs1!Confirmed, and the value yet to confirm in rs1!YetToConfirm
Then here:
Do While Not rs2.EOF
rs2.Edit
rs2!FinalExpenditure = rs1!Final
rs2.Update
rs2.MoveNext
Loop
change it to:
Do While Not rs2.EOF
rs2.Edit
rs2!FinalExpenditure = Iif(rs1!YetToConfirm = 0, rs1!Confirmed, 0)
rs2.Update
rs2.MoveNext
Loop
One way to process this would be check using a subquery whether last year(verified using a dmax function) in each project has been checked in the final column, if this is true, get your sum of checked amounts, else dont calculate the sum.
I have modified your sql string to include this and I tested it against your given example to confirm its showing a sum of $300 or nothing.
SQL = ""
SQL = SQL & " SELECT Sum(Amount) as Final From Expenditures "
SQL = SQL & " Where ProjNo = '" & Me.ProjNo & "' And Final = True "
SQL = SQL & " And (SELECT Expenditures.Final FROM Expenditures where year = ( "
SQL = SQL & " DMax('Year','Expenditures','ProjNo= " & Chr(34) & Me.ProjNo & Chr(34) & "'))) = true "
SQL = SQL & " Group by ProjNo "
This is my code for insert and update statement:
For i = 0 To lvFabric1.Items.Count - 1
strQ4 = ""
strQ4 = strQ4 & "INSERT into js_det(LINE_NO, FABRIC1, FABRIC2, `DESC`) SELECT LPAD('" & i + 1 & "',2, '0'), '" & lvFabric1.Items(i).Text & "','sdf', `DESC` from rm_inv where ITEM_CODE = '" & lvFabric1.Items(i).Text & "'"
strQ5 = ""
strQ5 = strQ5 & "UPDATE js_det set TRAN_NO = (SELECT JS_TRAN FROM counter) where Fabric1 = '" & lvFabric1.Items(i).Text & "'"
cmd.CommandText = strQ4
cmd.ExecuteNonQuery()
cmd.CommandText = strQ5
cmd.ExecuteNonQuery()
Next
What the problem here is that its getting slower if it is looping 5 times and above, it take above 3 second. How can I speed up this code? or is there another way?
Thanks for the help.
To speed it up, commit the whole thing in one go, somthing like:
Dim sqls As New List(Of String)
For i = 0 To lvFabric1.Items.Count - 1
sqls.Add("INSERT into js_det(LINE_NO, FABRIC1, FABRIC2, `DESC`) SELECT LPAD('" & i + 1 & "',2, '0'), '" & lvFabric1.Items(i).Text & "','sdf', `DESC` from rm_inv where ITEM_CODE = '" & lvFabric1.Items(i).Text & "'")
sqls.Add("UPDATE js_det set TRAN_NO = (SELECT JS_TRAN FROM counter) where Fabric1 = '" & lvFabric1.Items(i).Text & "'")
Next
If sqls.Any() Then
cmd.CommandText = sqls.Aggregate(Function(m, n) m & ";" & n)
cmd.ExecuteNonQuery()
End If
However, it's not a recommended way to do sql query in .net.
SQL parameter should be used to avoid any sql injection or sql syntax error.
EDIT: using sql parameter -
Using con As New SqlConnection("My connection string..."),
cmd As New SqlCommand(sql, con)
cmd.CommandText = "UPDATE js_det set TRAN_NO = (SELECT JS_TRAN FROM counter) where Fabric1 = #fabric"
Dim fabricParam = cmd.Parameters.Add("#fabric", SqlDbType.VarChar)
con.Open()
For i = 0 To lvFabric1.Items.Count - 1
fabricParam.Value = lvFabric1.Items(i).Text
cmd.ExecuteNonQuery()
Next
con.Close()
End Using