VBA While loop using an SQL statement as my While - sql

I'm writing some code behind some spreadsheets and I need to loop through some code, like getting data from a database doing some formulas and moving the data to a new sheet. My code for getting the data from the database is getting all of the values in multiple columns where the data has not been reported and has the same file name ( the data is coming from a file ), I have a field which states whether or not it has be reported by a simple "Y" or "N", and a field which holds the filename it came from.
So I need a while that, "WHILE" there's data that hasn't been reported do the rest of my code ( this includes my first SQL statement I said as this get data that hasn't been reported from each individual filename ).
I've been trying to get this to work for days but just have not been able to figure out how, so any help would be very grateful.
Update:
Database has a entity called datareported, can either be "N" or "Y", and also datadatfile which is the name from which the data came from.
So,
WHILE datareported = 'N' THEN
"SELECT (the data rows I want)
FROM tbldata
WHERE datareported='N' and datadatfile =
(SELECT min(datadatfile)
FROM tbldata WHERE datareported='N')"
This means that I loop through the rest of my code WHILE there is data that hasn't been reported and only bring in data of the same name ( from datadatfile ) so that the code can be run on that data.
That's basically what I want to do and that's pretty much what I have tried. I have tried a few other things and normally get a return of type mis-match.
Cheers,
Sam

More information needed for a solution but this may be of some help to push you in the right direction...
'ws1 = worksheet object...
bC = true
cnt1 = 2 ' starting row
Do While bC
If ws1.cells(cnt1, 1) = "N" Then
'Run your SQL here
Else
'Already reported...
End If
cnt1 = cnt1 + 1
If 'you hit the last row on your worksheet set bC = False to exit loop
Loop
Missed the update...this wont help, sorry.

Related

Insert Into SQL not working

I have a table named cpns with fields as C_Bk_No (Coupon book number), St_No (starting coupon number) and End_No (number of the last coupon) all integers.
I have initiated the table with first record as 1, 1, 25.
I am trying to get the system insert new rows with cpn number + 1, start_No + 25 and End_No + 25 as the new record on clicking a button (Command13) on the form.
Thus, the expected second record should have cpn_bk_no = 2, St_No = 26, End_No = 50.
I am not sure why the following SQL is not working:
Private Sub Command13_Click()
Dim Sql As String
Dim CbkNo As Long
Dim StNo As Long
Dim EndNo As Long
CbkNo = Me![C_bk_No].Value + 1
StNo = Me![St_No].Value + 25
EndNo = Me![End_No].Value + 25
Sql = "Insert Into cpns ([C_bk_No], [St_No], [End_No]); Values (CBkNo, StNo, EndNo))"
CurrentDb.Execute Sql
End Sub
Every time I click the button, it says "Run time error 3061, Too few parameters: Expected 3." and the line "CurrentDb.Execute Sql" is highlighted in yellow.
Please can anyone help?
It's difficult to know where to begin with this, but the basic problem you're facing is that you've typed the names of your variables into the string. Unlike some other languages, vb doesn't look at your string contents and think "oh, he's typed a variable name into that string, I'll jut swap it for the value currently in the variable"
There are other problems with this code too, but not quite so fundamental as that. I'd genuinely recommend you throw all that code away and follow this tutorial instead, about how to access a database in one of the ways Microsoft recommends:
https://msdn.microsoft.com/en-us/library/ms171884.aspx
Even if you're not making a win forms app the concepts there inside can be applied to all kinds of app
This semicolon is wrong. Semicolons are use to separate sql statements from each other.
Insert Into cpns ([C_bk_No], [St_No], [End_No]) **;** Values (CBkNo, StNo, EndNo)
remove it and put it at the and it will work:
Insert Into cpns ([C_bk_No], [St_No], [End_No]) Values (CBkNo, StNo, EndNo);

.Select return wrong length

I'm trying to check if the field data of my DataTable records is set to '0' or '1'. All my local record is saved into local_ds DataTable. Now, the record that I want check is this: 21a956af-f304-4c72-97cf-1ef08e8719fc
for a better vision I paste here the content of my table (that is also the content of my DataTable local_ds):
How you can see the record that I want check have the field data set to 0. Now I perform the research through this code:
Dim local_data = local_ds.Tables(0).Select(String.Format("GUID = '{0}'", "21a956af-f304-4c72-97cf-1ef08e8719fc"), String.Format("data", 1))
The code above use LINQ to take the result, anyway, I pass the GUID field to search and the field data as 1. This code should be return local_data.length equal to 0 but, instead, return 1 and this is wrong, 'cause I want to check only if the field data is 0 or 1. In this example the result should be local_data.length = 0 'cause in the LINQ query I specified clearly that I want find the record with GUID = x and data = 1.
I already know that this record exists in the database, the local_data variable must help me to recognize which type of valorization the data field have.
So, what I did wrong?
No, in the code above, you are not using LINQ.
DataTable.Select is a method available starting from the 1.1 version of NET Framework and exists in four possible overloads.
The one you are using is the one that takes, as first parameter, the WHERE condition and, as second parameter, the SORT order. So you are not really passing a condition WHERE .... AND Data = 1 but the Data=1 it is interpreted as a sort order of some kind.
The correct string for the WHERE parameter should be
Dim where as String = String.Format("GUID = '{0}' AND Data = {1}", _
"21a956af-f304-4c72-97cf-1ef08e8719fc", 1)
Dim local_data = local_ds.Tables(0).Select(where)

Pivot table filter raises error when empty

.I have multiple pivot tables. When I open the workbook, I am forcing excel to select filters using:
Sheets("PSD").Select
'Update table 7 Number of PSDs scheduled by Month
ActiveSheet.PivotTables("PivotTable7").PivotFields("Adhoc").CurrentPage = _
"No"
ActiveSheet.PivotTables("PivotTable7").PivotFields("Type").CurrentPage = _
"PSD Inspection"
'Update table 8 Number of PSDs scheduled by Month
ActiveSheet.PivotTables("PivotTable8").PivotFields("Adhoc").CurrentPage = _
"No"
ActiveSheet.PivotTables("PivotTable8").PivotFields("Type").CurrentPage = _
"PSD Inspection"
The problem is when there is no data with that filter as expected, I am getting an error.
How can I create a condition where I check if the filter exists and if it does, force the filter to what I want, else skip it.
would getpivotdata work? getpivotdata will return an error for cases where the "index" doesn't exist or else 0 for cases where "index" exists but no data exists (or sums to 0)
instead of using getpivotdata in VBA itself, you might prefer to add a new worksheet with getpivotdata and other formulas that determine which filter you need, then refer to this worksheet in your VBA.
if you structure this properly, you could then change the rules / formula in this new worksheet to drive changes to the filtering logic without having to edit VBA - this will make troubleshooting easier also.

Conversion of Varchar to int

Need help! I cannot retrieve data in SQ L, because the value is 100-200
and it says that it needs to be converted it to Integer, but it is Var char data type.
So i think the problem is about the "-", then the error in the code is in
the data table code, so what to do?
Private Sub RetriveData(ByVal ID As String)
If Sql.HasConnection() = True Then
Dim DT As DataTable = Sql.ExecuteDataTable("SELECT (EmpID As varchar), FirstName,MidName,LastName,Gender,BirthDate,CivilStat,Address,ContactNum FROM EmployeeTable Where EmpID=" & ID)
For Each Data As DataRow In DT.Rows
EmpID_Txt.Text = Data(0)
FirstName_Txt.Text = Data(1)
MiddleName_Txt.Text = Data(2)
LastName_Txt.Text = Data(3)
Gender_CB.Text = Data(4)
BirthDate_DTP.Value = Data(5)
CivilStat_CB.Text = Data(6)
Address_Txt.Text = Data(7)
Contact_Txt.Text = Data(8)
Next
Else
MsgBox("System Database Cannot be Connected", MsgBoxStyle.Information)
End If
End Sub
Pass the ID as SQL Parameter to your query:
"SELECT (EmpID As varchar), FirstName,MidName,LastName,Gender,BirthDate,CivilStat,Address,ContactNum FROM EmployeeTable Where Empid=#empid"
Actually, assuming those 100-200 values are in a table somewhere, I would say the error was in the cranium of the developer who decided to use a varchar to store a numeric value :-)
Either that, or the developer who decided to take an otherwise free-form text field and assume it was always going to be a single numeric value.
As to how to fix it, one of those paragraphs simply needs to be worked around. If you want a single numeric value in the table, you should change it to a numeric type field, along the way going through all 100-200 style values and cleaning them up (into, for example, 150).
If you want to be able to store ranges, then your code that processes them is going to have to be more intelligent, such as extracting the lower and upper value from the column and running a loop to process all values within the range, or changing a query from (pseudo-codish query):
where EmpId = ?value?
into:
where EmpId >= ?low? and EmpId <= ?high?
We can't really tell you which is the best solution based on the information provided, this is likely to be a business decision rather than a technical one.
If my assumption is wrong and it's the ID argument (being used in the where clause) to the function RetriveData (sic), then you either need to stop users entering that, or make the code that processes the argument more intelligent (similar to the looping/changed-query suggestion above).

Checking for date overlap across multiple date range objects

I have several records in a database that have Start and End Dates
09/15/2011 - 09/30/2011
10/15/2011 - 10/22/2011
11/01/2011 - 11/15/2011
When user stores a record, I need to make sure dates don't overlap.
My simple code checks date ranges within a specific record (e.g. user enters 9/16/2011 or 10/21/2011, I throw an exception.)
But, on the slim chance a user gets creative (e.g. 10/14/2011 - 10/23/2011 or even 10/14/2011 to 11/16/2011), now they have circumvented my check.
BTW, the user could enter 10/14/2011 to 10/23/2011 if they were editing the record that contained values 10/15/2011 - 10/22/2011.
So, I'm trying to solve this riddle with a linq query. However, what I have isn't working exactly right.
UPDATE Nevermind about code not working. While trying to provide an example to expand on Miika's repsonse, I found my answer. So, giving credit to Miika for pointing me in the right direction and posting my working code below:
Here's my code:
Private Sub CheckForOverlap(myMonth As Messages.MyMonth)
Dim am As New MyMonth()
Dim amCollection As Messages.MyMonthCollection
Dim overlappingMyMonthDate As Boolean = False
Dim sErrorMsg As String = ""
'...non-applicable code omitted
Dim query = From s In amCollection _
Let s1 As MyMonth = CType(s, MyMonth) _
Where s1.AttendanceMonthID <> attendanceMonth.AttendanceMonthID And _
(CDate(attendanceMonth.StartDate) < CDate(s1.StartDate) And CDate(attendanceMonth.EndDate) > CDate(s1.EndDate)) _
Select s1
If query.Count > 0 Then
sErrorMsg = "Dates entered surround another entry"
End If
If overlappingMyMonthDate Then
Throw New Exception(sErrorMsg)
End If
End Sub
End Class
It all came down a LINQ query.
Do you need to do it in code or would SQL be an option? If the data is in a database, you could use the following query to check for overlaps.
SELECT COUNT(*)
FROM Table1
WHERE Table1.StartDate < 'endCheckDate'
AND Table1.EndDate > 'startCheckDate'
This will return a count of the number of overlaps found. 'endCheckDate' and 'startCheckDate' are your new query values (in date format). If your data is in a object collection in memory, then you could use LINQ. If you need help with a LINQ statement, let me know.