I want to give the user the option to press "set print area" and the area printed is determined by which date they fill in.
The 2nd row always contains today's date. and then there is 2 years of data after that. Maybe the user only wants to print for first 3 months.
So the set print area code should be written something like.
row = len(date max - len today)
I am very new to VBA, so have no clue how to write this.
thank you!
I'm not sure why you want to use VBA to do this when you can just use 'Filter' on the data you have. On the date column you can then use the in-built 'Date Filters' to filter out any range of data. Once you specify the filter, print command will only print the filtered data set and not the complete data set.
Anyways if you want the row it can also be achieved via Excel Formula:
=ADDRESS([dataset_first_row]+MATCH([set_print_area_date_cell],[dataset_date_range],-1)-1,2,4,1)
Related
I am having some problem with using a countifs formula in Excel / VBA. I have got the formula working perfect in Excel but ideally I want to use this in VBA with my form. Here is the formula in Excel which works a treat:
=COUNTIFS(Sheet1!A:A,"Place",Sheet1!K:K,"<"&TODAY())
will count the names places that are now in the past
=COUNTIFS(Sheet1!A:A,"place",Sheet1!K:K,">"&TODAY())
will count the names places that are current
I have five different Places in column A and hundreds of different dates in column K. The above formulas work well in Excel and return the correct values. I have spent hours trying to get this to work in VBA with my userform but keep getting various errors. The first part is not the problem but as soon as I get to the &today function it falls apart. From what I can see the &today function is not available in VBA and the &Date seems to be the recommendation. I have tried this but still get no where. I'm missing a trick (or several) here and I would really like to get this working in VBA rather than using the current formulas in Excel. The returned results are then displayed in textboxes on my form.
All ideas and feedback much welcome!
Second edit
================================
Thanks for the quick replies! Here is the actual code I am playing about with in VBA
'Count events by area'
Dim ListLondon As Long
ListLondon = .CountIf(Range("a1:a1998"), "London"), ("Sheet1!K1:K1998"), "<" & Date)
End With
Me.TextBox1 = ListLondon
I know the second part of the count if is all wrong regards the date - that's how I've left it for now. I am really hoping to use the current layout and a working Date / Today code at the end. Please show me what I've done wrong here!
====
oops - can see a mistake already - but the initial problem remains around the date issue. I should of used countifs as using multiple criteria.
You have to read the values of the cells to your VBA code. I recommend you to use Excel.Range object to do that. It can interpret the range like the edit line of the Excel, something like
Dim foo as Excel.Range
set foo = yourworksheet.Range("A1:B3")
Read the Date type data into VBA Date type variable by iterating through the cells.
Examine relation between the read data and the current date. Current date can be read by using the DateTime.Now function.
Increment a variable based on a decision
Using Excel, lets say I have a validation list made of 5 values like this one :
Patate
Tomate
Courgette
Concombre
Patate
In a cell containing a drop down list made of these 5 value, I select the fifth value : "Patate".
I want to get in VBA that this cell contains the 5th value of my validation list. Something like :
x = Cell.Validation.GetIDValueSelected
x = 5
I can't use Vertical search because I might have 2 or even more time the same value in my list (too long to explain why).
This list is also dynamics (depending of another sheets) so it doesn't always contains 5 values.
I hope I made it clear for everyone to understand my needs but I will be glad to add more information if needed.
Thank you for your time.
Sadly, once you have used DV to fill a cell with junk, there is no way to tell which piece of junk you picked:
You would have to pad each piece of junk with a different number of blanks.
I am a little stuck at the moment. I am working on an array of data and need to find a way to input column numbers into formulas.
-I have used the match function to find the corresponding column number for a value.
ex. "XYZ" matched with Column 3, which is equivalent to C1:Cxxxxxx
-now for inputing the C1:Cxxxxxx into a formula to get data for that particular column, I would like to be able to directly reference the Column 3 part, because I plan on using this workbook in the future and the column needed to run the calculation may or may not be column 3 the next time I use it.
- is there any way to tell excel to use a formula to tell excel which column to use for an equation?
so a little more detail, I have the equation
=AND(Sheet3!$C$1:$C$250000=$A$4,Sheet3!$B$1:$B$250000=$B$4)
instead of specifying to use column C, is there a way to use a formula to tell it to use C?
EDIT: more additional info;
"i am basically running the equivalent of a SQL where statement where foo and bar are true, I want excel to spit out a concatenated list of all baz values where foo and bar are true. ideally i would like it to ONLY return baz values that are true, then I will concat them together separately. the way I got it now, the expression will test every row separately to see if true; if there is 18K rows, there will be 18K separate tests.. it works, but it's not too clean. the goal is to have as much automated as possible. *i do not want to have to go in and change the column references every time I add a new data arra*y"
Thanks
You can use INDEX, e.g. if you have 26 possible columns from A to Z then this formula will give you your column C range (which you can use in another formula)
=INDEX(Sheet3!$A$1:$Z$250000,0,3)
The 0 indicates that you want the whole column, the 3 indicates which column. If you want the 3 can be generated by another formula like a MATCH function
Note: be careful with AND in
=AND(Sheet3!$C$1:$C$250000=$A$4,Sheet3!$B$1:$B$250000=$B$4)
AND only returns a single result not an array, if you want an array you might need to use * like this
=(Sheet3!$C$1:$C$250000=$A$4)*(Sheet3!$B$1:$B$250000=$B$4)
You could use ADDRESS to generate the text, you then need to use INDIRECT as you are passing a string rather than a range to the fomula
=AND(INDIRECT(ADDRESS(1,3,,,"Sheet3") & ":" & ADDRESS(250000,3))=$A$4
,INDIRECT(ADDRESS(1,2,,,"Sheet3") & ":" & ADDRESS(250000,2))=$B$4)
Obviously replace the 3s and 2s in the ADDRESS formulae with your MATCH function you used to get the column number. The above assumes the column for $B$1:$B$25000 is also found using `MATCH', otherwise it is just:
=AND(INDIRECT(ADDRESS(1,3,,,"Sheet3") & ":" & ADDRESS(250000,3))=$A$4
,Sheet3!$B$1:$B$25000=$B$4)
Note a couple of things:
You only need to use "Sheet3" on the first part of the INDRECT
Conditions 3 and 4 in the ADDRESS formula are left as default, this
means they return absolute ($C$1) reference and are A1 style as
opposed to R1C1
EDIT
Given the additional info maybe using an advanced filter would get you near to what you want. Good tutorial here. Set it up according to the tutorial to familiarise yourself with it and then you can use some basic code to set it up automatically when you drop in a new dataset:
Paste in the dataset and then use VBA to get the range the dataset uses then apply the filter with something like:
Range("A6:F480").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:= _
Sheets("Sheet1").Range("A1:B3"), Unique:=False
You can also copy the results into a new table, though this has to be in the same sheet as the original data. My suggestion would be paste you data into hidden columns to the left and put space for your criteria in rows 1:5 of the visible columns and then have a button that gets the used range for your data, applies the filter and copies the data below the criteria:
Range("A6:F480").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Sheets _
Range("H1:M3"), CopyToRange:=Range("H6"), Unique:=False
Button would need to clear the destination cells first etc, make sure you have enough hidden columns etc but it's all possible. Hope this helps.
I am a pilot, and use a logbook program called Logten Pro. I have the ability to take excel spreadsheets saved from my work flight management software, and import them into Logten Pro using the CSV format.
My problem however, is that the work flight management software, exports the date and time of take-off of a flight into one cell in the following excel format: DD/MM/YYYY H:MM:SS PM.
This is handled fine by Excel, and is formatted by default to DD/MM/YY even though the actual value is more specific, comprising of the full length date and time group.
This is a problem because Logten Pro will only auto-import the date if it is in DD/MM/YY format, and there is no way to pull out just the displayed DD/MM/YY date rather than the full date time group actual value, unless you manually go through and delete the extra text from the function box.
My question is: Is there a VBA macro that can automatically copy the actual displayed text, and paste it into another cell, changing the actual value as it does, to just the DD/MM/YY value? Additionally, can this be made to work down a whole column rather than individual cells at a time?
Note I have no VBA experience so the perfect answer would just be a complete VBA string I could copy and paste.
Thank You.
As pointed out in the comments, you'd better not use VBA but formulas instead.
This formula:
TEXT(A1,"dd-mm-yyy")
will return the formated date in a text way. You can drag and drop the formula in the whole range of your cells and Copy/Paste Special > Values so that you will only have the needed values to get imported in Logten Pro.
There are three options using formulas.
Rounddown
Excel stores the date time as a number and uses formatting to display it as a date.
The format is date.time, where the integer is the date and the fraction is the time.
As an example
01/01/2012 10:30:00 PM is stored as 40909.9375
All the values after the decimal place relate to the hours and minutes
So a formula could be used to round the number down to a whole number.
=ROUNDDOWN(A1,0)
Then format the value as a short date.
It will then display as 01/01/2012
INT
As above, but using a different formula to get rid of the fraction (time)
=INT(A1)
Text
Alternately the date only could be extracted as text using this formula
=TEXT(A1,"dd/mm/yyyy")
It will then display as 01/01/2012
I'm a bit late to the party on this one, but recently came across this as was searching for answers to a similar problem.
Here is the answer I finally came up with.
Option Explicit
Sub ValuesToDisplayValues()
Dim ThisRange As Range, ThisCell As Range
Set ThisRange = Selection
For Each ThisCell In ThisRange
ThisCell.Value = WorksheetFunction.Text(ThisCell.Value, ThisCell.NumberFormat)
Next ThisCell
End Sub
This answers the question as asked, apart from the new values are pasted over the existing ones, not into a new cell, as there is no simple way to know where you would want the new values to be pasted. It will work on the whole range of selected cells, so you can do a whole column if needed.
I have one sheet which is comprised of data that was imported from a web page. In a second sheet I have a cell asking for min price and max price which comes from the imported data. The issue is that the data can move to different cells when it's refreshed so my code needs to look for some specific wording to find the prices that I need rather than just directing it to the same cell each time
The info in the imported data sheet which I need to extract from will always be in this string of text which will always be found somewhere between row 15-35 but will move when the website is refreshed. The 1st number (71.00) needs to be extracted to another sheet in a cell asking for min price while the second number (75.00) is the max price. These prices can change so I can just look for those numbers and extract them.
SLAUGHTER BULLS: Yield grade 1-2 1000-1500 lbs
1500-2000 lbs 71.00-75.00.
Could someone please help me with the coding for this macro?
Use the InStrRev function (similar to the LastIndexOf function in .NET) to find the last index of "lbs" in the test string.
lastIndex = InStrRev(testString, "lbs", 1, 1)
Then search from that last index to the end of the string spliting on the -
splitArray = Split(Mid(testString, lastIndex, Len(testString) - lastIndex), "-", 1)
The lowest value will be in splitArray(0) and the upper value will be in splitArray(1) assuming a zero indexed array.