I am trying to use code to filter a spreadsheet dynamically, based on the current date.
I am storing the date I need to filter on as "CurrDay" and I'm attempting to recall that stored date back into my filter algorithm. It is not working and I need to figure out how to do this to finish up this code. Everytime I run the code it returns the CurrDay name in the filter instead of the date stored under the CurrDay variable.
I'm missing something here and I need some direction. Any help is appreciated.
CODE:
Sub Finishing_A59_Filter()
'
' Finishing_A59_Filter Macro
' This macro will activate the A59 and Filter it properly for standard orders
'
'This macro does not include the VMI's and APS orders in the code
'
'
Dim Currday As Date
Currday = Date + 7
UName = Application.UserName
Workbooks.Open Filename:="G:\Copy Modified A59 5-19-2009.xlsm", UpdateLinks _
:=0
Range("M2").Select
ActiveCell.Value = Currday
Columns("Q:Q").Select
Selection.NumberFormat = "mm/d/yyyy"
' Filter the sheet to remove VMI's and APS orders
ActiveSheet.Range("$A$3:$AA$2941").AutoFilter Field:=23, Criteria1:=Array( _
"01", "04", "06", "08", "09", "10", "15", "25", "="), Operator:=xlFilterValues
' Set the proper date range for the sheet - This needs to be seven days beyond the current date
ActiveSheet.Range("$A$3:$AA$2941").AutoFilter Field:=17, Criteria1:= _
"<=Currday", Operator:=xlAnd
You need to concatenate the variable with the criteria string.
ActiveSheet.UsedRange.AutoFilter Field:=17, Criteria1:= _
"<=" & Currday, Operator:=xlAnd
Also, it's better to use "UsedRange" instead of making up a big range because it doesn't work if your data extends past your arbitrary range and is a waste of resources if it doesn't.
Related
I'm trying to code so that one of the pivot filter the current month. But it's giving me an error
Sub Macro1()
'
' Macro1 Macro
Dim Lmonth As Integer
Lmonth = Month(Worksheets("Cash Receipts").Range("A1").Value)
'
ActiveSheet.PivotTables("PivotTable1").PivotFields("[Date].[Month].[Month]"). _
VisibleItemsList = Array("[Date].[Month].&[2018-]&Lmonth&[-01T00:00:00]")
End Sub
Please help.
Date format Shows Invalid Date With Custom Date. When I use 'Date' instead of "25th May" it shows yesterday's Date.
function GetYD()
Dim dt, yesterday
dt = DateAdd("d", -1, "25th May")
yesterday = Right(Year(dt),2) & Right("0" & Month(dt),2) & Right("0" & Day(dt),2)
msgbox yesterday
GetYD = yesterday
end function
Be sure to feed it a string that can be parsed. Always use digits if possible, and you did not even specify a year.
The format yyyy-mm-dd would probably work best, as it is (both to humans and to computers) totally un-ambiguous. So try it using
DateAdd("d", -1, "2017-05-25")
I want to make an Excel workbook that I have much quicker.
I have a big product database with the product names, quantities, delivery number and delivery date (ProductDB). I put in another sheet the products that I have sold (product names and quantity sold) and want to filter and copy those that are corresponding from the database so I can calculate in the second step the remaining quantity and past the remaining quantity to the database.
Everything is working well and the calculation is good. The only thing is, the Advancedfilter xlfiltercopy option is too slow if I have to input 5000 lines of product names.
I have heard that arrays are much faster. How could I do that? The current way I do it is like this:
Sub UseFilter()
Application.ScreenUpdating = False
Sheet1.Range("G1:Z100000").Cells.Delete
Dim lastrow As Long, c As Range
Dim myrange As Range
Dim rngCell As Range
Dim wksSheet As Worksheet
Dim wksSheetDB As Worksheet
lastrow = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row
Sheet1.Columns("G").NumberFormat = "0"
Filter product codes from the database according to sold product codes:
Set myrange = Range("A1:A" & lastrow)
For Each c In myrange
If Len(c.Value) <> 0 Then
ThisWorkbook.Worksheets(Worksheets.Count).Columns("A:D").AdvancedFilter xlFilterCopy, _
Sheet1.Range("A1:A" & lastrow), Sheet1.Range("G1"), False
End If
Next
Sort the filtered list first by product code, then by the delivery number:
Dim lngRowMax As Long
Dim wsf As WorksheetFunction
With Sheet1
lastrow = Cells(Rows.Count, 8).End(xlUp).Row
Range("G1:J" & lastrow).Sort Key1:=Range("G1:G" & lastrow), _
Order1:=xlAscending, Key2:=Range("I1:I" & lastrow), _
Order2:=xlAscending, Header:=xlYes, DataOption1:=xlSortTextAsNumbers
Set wsf = Application.WorksheetFunction
lngRowMax = .UsedRange.Rows.Count
End With
I'm only interested in filtering and copying of the corresponding product information (name (A), quantity (B), delivery nr (C) and date (D)). Does anyone know how I can do that?
Thank you very much in advance. I'm really looking forward for a solution that improves the pace of the file. Currently it is unbelievably slow.
i had the same problem with advanced filter being so slow. you might want to consider using dictionary. for my 2 spreadsheets i wanted to compare i made 2 dictionaries and compared the values and it was so amazingly fast. dictionaries are really easy and a simple google search you can find a ton of tutorials and examples. good luck.
There is a possible solution with dictionaries, but I have only one small issue. I will explain after the code:
'Count num rows in the database
NumRowsDB = ThisWorkbook.Worksheets(Worksheets.Count).Range("A2", Range("A2").End(xlDown)).Rows.Count
' --------------------- SAVE DATABASE DATA -----------------------
'Dictionary for all DB data
Set dbDict = CreateObject("Scripting.Dictionary")
Set dbRange = Range("A2:A" & (NumRowsDB + 1))
For Each SKU In dbRange
If Len(SKU.Value) <> 0 Then
' check if the SKU allready exists, if not create a new array list for that dictionary entry
' a list is necessary because there can be multiple entries in the db range with the same SKU
If Not dbDict.Exists(CStr(SKU.Value)) Then
Set prodList = CreateObject("System.Collections.ArrayList")
dbDict.Add CStr(SKU.Value), prodList
End If
' for this specific product code, save the range where the product information is saved in the dictionary
rangeStr = "A" & SKU.Row & ":D" & SKU.Row
dbDict(CStr(SKU.Value)).Add (rangeStr)
End If
Next
' ----------- READ SALE/Reverse/Consumption INFO ------------------
NumRowsSale = Range("A2", Range("A2").End(xlDown)).Rows.Count
Set saleRange = Range("A2:A" & (NumRowsSale + 1))
Dim unionRange As Range
For Each sale In saleRange
' check if the SKU for the sale exists in db
If Len(sale.Value) <> 0 And dbDict.Exists(CStr(sale.Value)) Then
For Each dbRange In dbDict(CStr(sale.Value))
If unionRange Is Nothing Then
Set unionRange = Range(dbRange)
Else
Set unionRange = Union(unionRange, Range(dbRange))
End If
Next
End If
Next
unionRange.Copy Destination:=Range("G2") 'copy all received ranges to G2
Set dbDict = Nothing
The line "NumRowsDB = ThisWorkbook.Worksheets(Worksheets.Count).Range("A2", Range("A2").End(xlDown)).Rows.Count" is not working. I have to refer to another sheet (the last sheet which is the current database) to get the data. What is the problem that I cannot refer to another sheet in the same workbook?
Thank you for your suggestions.
I'm having a hard time trying to gather data from an Oracle DB. I've managed to get the connection going, so the problem lies within the query. At the moment the query dont return anything, and neither VBA complains about it.
Here's the code:
Sub Connect_XXXX()
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
Dim rs As New ADODB.Recordset
Set rs = New ADODB.Recordset
Dim myQuery As ADODB.Command
Set myQuery = New ADODB.Command
conn.Open "Provider=OraOLEDB.Oracle;" & _
"Data Source=XXXX;" & _
"User Id=YYYY;" & _
"Password=ZZZZ"
myQuery.ActiveConnection = conn
myQuery.CommandText = "SELECT sta.index_id, sta.index_action as Action, sta.ticker, sta.company, sta.announcement_date as A_Date, sta.announcement_time as A_Time, " & _
"sta.effective_date as E_Date, dyn.index_supply_demand as BS_Shares, dyn.net_index_supply_demand as Net_BS_Shares, dyn.est_funding_trade as BS_Value, " & _
"dyn.trade_adv_perc/100 as Days_to_Trade, dyn.pre_index_weight/100 as Wgt_Old, dyn.post_index_weight/100 as Wgt_New, dyn.net_index_weight/100 as Wgt_Chg, " & _
"dyn.pre_est_index_holdings as Index_Hldgs_Old, dyn.post_est_index_holdings as Index_Hldgs_New, dyn.net_est_index_holdings as Index_Hldgs_Chg, sta.index_action_details as Details " & _
"FROM index_analysis.eq_index_actions_dyn dyn, index_analysis.eq_index_actions_static sta " & _
"WHERE (sta.action_id = dyn.action_id) AND (sta.announcement_date=dyn.price_date) AND (sta.announcement_date >= '01-January-2015') AND (sta.announcement_date <= '30-January-2015') " & _
"ORDER by sta.index_id,sta.announcement_date"
Set rs = myQuery.Execute
Sheets("Sheet1").Range("A1").CopyFromRecordset rs
rs.Close
conn.Close
End Sub
I've played around with the query a lot, and I've been able to get some results by removing some of the AND statements after the WHERE and trying with fewer fields on the SELECT statement, but I need them all in order for this results to work for me. The weird thing is that if I run the same query in a problem like Oracle Sql Developer (after connecting to the DB) it shows the results that I want. I could really use some help, Thanks!
If you are going to hard-code the date range, assuming announcement_date is a date, you'd want to compare against dates, not strings. You can use to_date with an explicit format mask to convert a string to a date,
sta.announcement_date >= to_date( '01-January-2015', 'DD-Month-YYYY')
or you can use a date literal which always has the format YYYY-MM-DD
sta.announcement_date >= date '2015-01-01'
My guess is that your code seems to work in SQL Developer because you happen to have configured your NLS_DATE_FORMAT to be 'DD-Month-YYYY' in SQL Developer.
In reality, you should really be using bind variables rather than hard-coding things like the date range. Assuming you bind a date value, the conversion (if any) from a string to a date would happen in VB and wouldn't depend on your session's NLS settings. There are also performance and security reasons to prefer bind variables.
I will explain my situation which will hopefully explain what I am trying to do. I have a table that has our staff phone numbers, but I need to be able to see what the next 5 available numbers are.
I have tbl_ext, which is current numbers and tbl_temp, which is used to enter in a "starting" number, dependent on status (managers get 1xxx, sales get 2xxx, etc) . I need to know if it would be possible to "count" the next 5 numbers that are not in tbl_ext and insert these into tbl_temp.
Hopefully this makes some sense, as I am starting to wonder if it is even possible.
The following code will create the next five numbers for extensions that start with '1xxx'. You didn't mention the format of the field (text or number), or if you store Area Code + Exchange + Ext.
You also didn't mntion how many different 'status' there are (1, 2, 3, ...). You can either clone the code and repeat for 1-9 or, you could select the unique high-order digit of all extensions. I can update the answer when you procide more detail.
Public Function Create_Phone_Numbers()
Dim db As Database
Dim rst As Recordset
Dim strSQL As String
Dim i As Integer
Dim iLoop As Integer
Dim iExt As Integer
Dim iStatus As Integer
Set db = CurrentDb
For iStatus = 1 To 9
If iStatus = 999 Then ' Change this line to skip unused numbers
' Do nothing - skip this
Else ' It's a number we want.
strSQL = "SELECT TOP 1 tbl_Ext.PhoneExt FROM tbl_Ext GROUP BY tbl_Ext.PhoneExt HAVING (((tbl_Ext.PhoneExt) Like '" & iStatus & "*')) ORDER BY tbl_Ext.PhoneExt DESC;"
Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)
If Not (rst.EOF And rst.BOF) Then
iExt = rst!PhoneExt
For i = 1 To 5
strSQL = "insert into tbl_Temp (PhoneExt) Select " & iExt + i & " As Expr1;"
db.Execute strSQL
Next i
End If
End If
Next iStatus
rst.Close
Set rst = Nothing
db.Close
Set db = Nothing
End Function