I have a cell with vehicle model years (starting A:2 and ending B:2) for example A:2 is 1997 and B:2 is 2001 How can I make the single cell C:2 show the range of years for example 1997 1998 1999 2000 2001 I need this for a shopping cart that will query specific years. My files have about 15,000 rows so I need to do this with a formula.
I need the end result to go into either the single cell c:2 or to populate in single cells to the right example c;2 d;2 e;2 etc. It is preferred to have them in a single cell separated by a space not a comma as this will be uploaded as a .csv file.
In C2 enter:
=A2
In C3 enter:
=IF( MAX($C$1:C2)=$B$2,"",C2+1)
and copy down
EDIT#1:
In order to place the result into a single cell run the following macro rather than using formulas:
Sub SpanOfYears()
Dim FirstCell As Range, SecondCell As Range, Result As Range
Dim I As Long
Set FirstCell = Range("A2")
Set SecondCell = Range("B2")
Set Result = Range("C2")
For I = FirstCell.Value To SecondCell.Value
Result.Value = Result.Value & " " & I
Next I
End Sub
with this result:
EDIT#2
Macros are very easy to install and use:
ALT-F11 brings up the VBE window
ALT-I
ALT-M opens a fresh module
paste the stuff in and close the VBE window
If you save the workbook, the macro will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the macro:
bring up the VBE window as above
clear the code out
close the VBE window
To use the macro from Excel:
ALT-F8
Select the macro
Touch RUN
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
Macros must be enabled for this to work!
Related
So I'm trying to pull the data in a row from a separate sheet (sheet2!), if part of Col A has the the Date that is in sheet1! C1.
Col A ex: "Build 251 at Fri Jun 12 03:03:49 2015"
Col C1 ex: "Fri Jun 12" (Changes date every couple days)
I've tried these formulas but they don't work. The errors I get back are "finished with no results"; "error filter has mismatched range sizes"; "there is no ColumnA"; "formula parse error"
=filter("'GitHub-Changelog'!A", ("'GitHub-Changelog'!A" = 'x64 RSS Data'!C2))
=QUERY('GitHub-Changelog'!A:F,"select * where A contains '(TRANSPOSE(" "&C1:C&" "))'")
=FILTER('GitHub Changelog'!A,MMULT(SEARCH(TRANSPOSE(" "&'x64 RSS Data'!C1:C&" ")," "&'GitHub-Changelog'!A1:A&" "),SIGN(ROW('GitHub-Changelog'!A1:A))))
I'm not sure why I'm not getting results, the date is in A. If I use this =QUERY('GitHub-Changelog'!A:F,"select * where A contains 'Fri Jun 12'") It prints out the single row, it's just not reading C1 for some reason; and I need it to be dynamic to match whatever C1 changes to.
*The true future ideal goal would be to check Sheet1!C against Sheet2!A, if part of A contains C then copy whole row (Sheet2!A:F) into a single cell (Sheet1!E). Along the lines of IF Sheet2!A contains sheet1!C1 then copy (sheet1!E=Sheet2!D&C&B, but I believe that needs full script writing to accomplish this so I'm not sure how to do it yet, but will learn; one thing at a time though (just thought I'd share a better version of what I'm trying to accomplish).
Here is the sheet I'm working on: https://docs.google.com/spreadsheets/d/1lPOwiYGBK0kSJXXU9kaQjG7WNHjnNuxy25WCUudE5sk/edit?usp=sharing. It pulls multiple pages on different sheets, then cleanup pages of the data. The plan is to have an update sheet that searches the changelog info for the date of the current build and puts that data next the build. So the final sheet will show most recent build + commit changes for that nightly build. That's where this function is being used, to scrape the changelog for the same date.
See if this works:
=query('GitHub-Changelog'!A:F; "where A contains '"&C1&"' ")
where C1 (on the same sheet as the formula) is the cell that holds the date (ex: Fri Jun 12).
You don't need to surround the range with "".
Also, you can use Find() in your filter, to check if that date is present in the string.
Here is a working Filter formula:
=FILTER('GitHub-Changelog'!A:F, Find('x64 RSS Data'!C1,'GitHub-Changelog'!A:A))
I'm importing an .xls file using the following connection string:
If _
SetDBConnect( _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filepath & _
";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""", True) Then
This has been working well for parsing through several Excel files that I've come across. However, with this particular file, when I SELECT * into a DataTable, there is a whole column of data, Item Description, missing from the DataTable. Why?
Here are some things that may set this particular workbook apart from the others that I've been working with:
The workbook has a freeze pane consisting of the first 24 rows (however, all of these rows appear in the DataTable)
There is some weird cell highlighting going on throughout the workbook
That's pretty much it. I can't see anything that would make the Item Description column not import correctly. Its data is comprised of all Strings that really have no special characters apart from &. Additionally, each data entry in this column is a maximum of 20 characters. What is happening? Is there any other way I can get all of the data? Keep in mind I have to use the original file and I cannot alter it, as I want this to ultimately be an automated process.
Thanks!
Some initial thoughts/questions: Is the missing column the very first column? What happens if you remove the space within "Item Description"? Stupid question, but does that column have a column header?
-- EDIT 1 --
If you delete that column, does the problem move to another column (the new index 4), or is the file complete. My reason for asking this -- is the problem specific to data in that column/header, or is the problem more general, on index 4.
-- EDIT 2 --
Ok, so since we know it's that column, we know it's either the header, or the rows. Let's concentrate on rows for now. Start with that ampersand; dump it, and see what happens. Next, work with the first 50% of rows. Does deleting that subset affect anything? What about the latter 50% of rows? If one of those subsets changes the result, you ought to be able to narrow it down to an individual row (hopefully not plural) by halfing your selection each time.
My guess is that you're going to find a unicode character or something else funky is one of the cells. Maybe there's a formula or, as you mentioned, some of that "weird cell highlighting."
It's been years since I worked with excel access, but I recall some problems with excel grouping content into some areas that would act as table inside each sheet. Try copy/paste the content from the problematic sheet to a new workbook and connect to that workbook. If this works you may be able to investigate a bit further about areas.
I'm really new to the use of closedXMl and Excel too(at least for this purpose) so sorry if I'm asking silly questions.
I know that closedXML doesn't support charts yet so the only thing that came to mind to get around this was to create my chart using an excel table . That way I thought ClosedXML would update the ranges when I inserted new rows and the chart would pick up on it. Well , it didn't. At least not when I add the rows from code using the closedXML library.
What is curious is that adding new rows from inside excel automatically updates the chart but if I want to get that same result from code, I have to use OFFSET formula along with named ranges and then set the chart source data to these named ranges.
That's why I'd like to know if if there is anything wrong with the code I use to insert new rows:
Dim ruta As String = Server.MapPath("~/Templates/MyTemplate.xlsx")
Dim wb As New XLWorkbook(ruta)
Dim ws = wb.Worksheet(1)
Dim tblData = ws.Table("Table1")
Dim year As Integer = 2000
For i As Integer = 1 To 13
With tblData.DataRange.LastRow()
.Field("Year").SetValue(year)
.Field("Sales").SetValue(CInt(Math.Floor((2000 - 500 + 1) * Rnd())) + 500)
End With
tblData.DataRange.InsertRowsBelow(1)
year = year + 1
Next
tblData.LastRow.Delete()
As you can see the code is very simple and so is the template , that consists of only two columns : "Year"(table1[Year]) and "Sales"(Table1[Sales]
I don't think this has anything to do with my template because as I told you, adding new rows directly from excel works as expected and it is only when I generate the table from code that the chart series doesn't include the new row that were added
Being necessary to manually add the new ranges(Sheet1!Table1[Sales] and Sheet1!Table1[Year]) as it only includes the first row(the one added by default when you insert a table)
Any help would be much appreciated
P.S. Here is a link to a rar containing the full code as well as the excel template(\Templates\MyTemplate.xlsx)
If the problem is that your table doesn't recognise the additional rows, try adding this after the last row delete:
tblData.Resize tblData.Range(1, 1).CurrentRegion
That should resize the table. Then hopefully your table operations should work.
I am working with Excel 2003 and trying to find the total of individual criteria. I am currently using this formula and it is working successfully.
Data A1:G1776 is the the database ---
Data C1 - is the column that has what I want total --- and
F4:F5 is a column where I set up a the criteria for the line to match.
=DSUM(DATA!$A$1:$G$17996,DATA!$C$1,$F$4:F5)
The problem I am running into is that the file size is over 5MB, which is huge when you are trying to email it to other people.
Any suggestions how I can replicate that formula, while decrease the file size and also improving the speed of the document? I am not wishing to use a Pivot Table
A replacement for DSUM, you could use a sumproduct formula:
=SUMPRODUCT((DATA!$C$2:$C$17996)*(DATA!$A$2:$A$17996="Boys")*(DATA!$B$2:$B17996>18))
The above example creates a total of column C only including rows where: Column A are "boys and column B is greater than 18.
The example assumes that row 1 is a header row.
For speeding up calculations you could use VBA to enable calculation of indvidual sheets.
VBA for enabling calculation:
Public Sub enableCalc(ParamArray sheetsInUse())
Dim i As Integer
For i = 0 To UBound(sheetsInUse) Step 1
sheetsInUse(i).EnableCalculation = True
Next i
End Sub
Called using: enableCalc activeworkbook.Worksheets("Sheet1")
Which would enable calculation Sheet1 in the activeworkbook
VBA for disabling calculation for all sheets in workbook:
Public Sub finishedUse(wrkbook As Workbook)
Dim i As Integer
Dim wrkSheet As Worksheet
For Each wrkSheet In wrkbook.Worksheets
wrkSheet.EnableCalculation = False
Next wrkSheet
End Sub
Called using: finishedUse activeworkbook
Which would disable calculation of all the sheets in the activeworkbook.
The above method isnt effected by changing Automatic/Manual Calculation in Tools --> Options
We have an automatic process that opens a template excel file, writes rows of data, and returns the file to the user. This process is usually fast, however I was recently asked to add a summary page with some Excel formulas to one of the templates, and now the process takes forever.
It successfully runs with about 5 records after a few minutes, however this week's record set is almost 400 rows and the longest I've let it run is about half an hour before cancelling it. Without the formulas, it only takes a few seconds to run.
Is there any known issues with writing rows to an Excel file that contains formulas? Or is there a way to tell Excel not to evaluate formulas until the file is opened by a user?
The formulas on the summary Sheet are these:
' Returns count of cells in column where data = Y
=COUNTIF(Sheet1!J15:Sheet1!J10000, "Y")
=COUNTIF(Sheet1!F15:Sheet1!F10000, "Y")
' Return sum of column where data is a number greater than 0
' Column contains formula calculating the difference in months between two dates
=SUMIF(Sheet1!I15:Sheet1!I10000,">0",Sheet1!I15:Sheet1!I10000)
' Returns a count of distinct values in a column
=SUMPRODUCT((Sheet1!D15:Sheet1!D10000<>"")/COUNTIF(Sheet1!D15:Sheet1!D10000,Sheet1!D15:Sheet1!D10000&""))
And the code that writes to excel looks something like this:
Dim xls as New Excel.Application()
Dim xlsBooks as Excel.Workbooks, xlsBook as Excel.Workbook
Dim xlsSheets as Excel.Sheets, xlsSheet as Excel.Worksheet
Dim xlsCells as Excel.Range
xls.Visible = False
xls.DisplayAlerts = False
xlsBooks = xls.Workbooks
xlsBooks.Open(templateFile)
xlsBook = xlsBooks.Item(1)
' Loop through excel Sheets. Some templates have multiple sheets.
For Each drSheet as DataRow in dtSheets.Rows
xlsSheets = xlsBook.Worksheets
xlsSheet = CType(xlsSheets.Item(drSheet("SheetName")), Excel.Worksheet)
xlsCells = xlsSheet.Cells
' Loop though Column list from Database. Each Template requires different columns
For Each drDataCols as DataRow in dtDataCols.Rows
' Loop though Rows to get data
For Each drData as DataRow in dtData.Rows
xlsCells(drSheet("StartRow") + dtData.Rows.IndexOf(drData), drDataCols("DataColumn")) = drData("Col" + drDataCols("DataColumn").toString).toString
Next
Next
Next
xlsSheet.SaveAs(newFile)
xlsBook.Close
xls.Quit()
Every time you write to a cell Excel recalculates the open workbooks and refreshes the screen. Both of these things are slow, so you need to set Application.Screenupdating=false and Application.Calculation=xlCalculationManual
Also there is a high overhead associated with each write to a cell, so it is much faster to acuumulate the data in an array and then write the array to the range with a single call to the Excel object model.
With auto mode calculation, recalculation occurs after every data input/changed. I had the same problem, was solved by setting Manual calculation mode. (Reference MSDN link.)
xls.Calculation = Excel.XlCalculation.xlCalculationManual
Also, this property can only be set after a Workbook has been opened or it will throw a run-time error.
One way that has saved me over the years is to add
Application.ScreenUpdating = False
directly before I execute a potentially lengthy method, and then
Application.ScreenUpdating = True
directly after, or at least at some later point in the code. This forces Excel to not redraw anything on the visible screen until it is complete That issue is where I've found lengthy running operations to stem from quite often.