How to declare cell range only with occupied range in excel - office-interop

I am working on an Excel based C# project where I have to put a whole column of data into a single dimensional array but I am unable to find proper way to do so.
The code I have used is although working but it drops the whole data of a column including unused cells (after the used range of my Excel column) into an array which wastes system resources.
any idea how to achieve this . I have tried the below code .
Excel.Range range3 = sheet.get_Range("A:A");

You'll need to infer the code prior to get the workbook and worksheet but try this ...
var lastCell = (Range)xlWorksheet.Range[$"A{xlWorksheet.Rows.Count}"].End[XlDirection.xlUp];
var values = ((Range)xlWorksheet.Range[$"A1:{lastCell.Address}"]).Value;
It will find the last visible cell in column A and then provide all of the values from A1 down to the last cell into an array.

Related

Combining multiple sheets with different columns using Power Query

I have a workbook with multiple pages that need to get combined, i.e. stacked, into one table. While they have many similar column names, they do not all have the same columns and the column order differs. Because of this I cannot use the inherent merge functionality because it uses column order. Table.Combine will solve the problem, but I cannot figure out to create a statement that will use the "each" mechanic to do that.
For each worksheet in x workbook
Table.Combine(prior sheet, next sheet)
return all sheets stacked.
Would someone please help?
If you load your workbook with Excel.Workbook you can choose the Sheet Kind (instead of Table or DefinedName kinds) and ignore the sheet names.
let
Source = Excel.Workbook(File.Contents("C:\Path\To\File\FileName.xlsx"), null, true),
#"Filter Sheets" = Table.SelectRows(Source, each [Kind] = "Sheet"),
#"Promote Headers" = Table.TransformColumns(#"Filter Sheets", {{"Data", each Table.PromoteHeaders(_, [PromoteAllScalars=true])}}),
#"Combine Sheets" = Table.Combine(#"Promote Headers"[Data])
in
#"Combine Sheets"
Load each table into Power Query as a separate query
fix up the column names as needed for each individual query
save each query as a connection
in one of the queries (or in a separate query) use the Append command to append all the fixed up queries that now have the same column names.

Excel 2017 Formula - Average data by month, while being filterable

I'm not a VBA coder, and I would prefer an excel formula if possible, the easiest solution will be the best one.
Test workbook screenshot
As you can see, I have plenty of columns, which are filterable.
I am attempting to retrieve an average of Column L, but I want the data to be calculated for the correct month in G3:R3.
The resulting calculation needs to be recalculated when filtered, between customers, sites, status, job type etc.
I am referencing the resulting cells in another sheet, which gives an idea of trends I can glance at, as such filtering by month in each sheet, is not an option.
=AVERAGE(IF(MONTH(E9:E1833)=1,(J9:J1833)))
This one does not update with the filtered data.
=SUM(IF(MONTH(E9:E1833)=1,J9:J1833,0)) /SUM(IF(MONTH(E9:E1833)=1,1))
This one does not update with the filtered data.
I have tried 5 different SUBTOTAL formulas, some with OFFSET, none of these produce the same result I get when checking manually.
Each worksheet has over 1,500 hundred rows, the largest is 29148 rows. The data goes back as far as 2005.
Please can someone help me find a solution?
One possible solution is to create a helper column which returns 1 if the row is visible and returns 0 if the row is invisible (or blank). This allows a bit more freedom in your formulas.
For example, if you want to create a helper column in column X, type this into cell X9 and drag down:
= SUBTOTAL(103,A9)
Now you can create a custom average formula, for example:
= SUMPRODUCT((MONTH(E9:E1833)=1)*(X9:X1833)*(J9:J1833))/
SUMPRODUCT((MONTH(E9:E1833)=1)*(X9:X1833))
Not exactly pretty but it gets the job done. (Note this is an array formula, so you must press Ctrl+Shift+Enter on your keyboard instead of just Enter after typing this formula.)
With even more helper columns you could avoid SUMPRODUCT altogether and just accomplish this by doing a single AVERAGEIFS.
For example if you type into cell Y9 and drag down:
= MONTH(E9)
Then your formula could be:
= AVERAGEIFS(J9:J1833,X9:X1833,1,Y9:Y1833,1)
There isn't a clean way to do this without at least one helper function (if you want to avoid VBA).

Is it possible to get the last row filled?

In gspread, is it possible to get the last row or cell number that is filled?
The API reference page doesn't seem to help.
Gspread has "row_count", but I am not sure it returns all rows in a spreadsheet, or just the filled ones. If that doesn't help, there is a slightly less direct, but completely functional way to do it:
1.) let's assume your data is in column A, and it has been filled in consecutively row by row (i.e. no skipped rows)
2.) in another free cell in your spreadsheet--let's assume cell B1--use the native Google Sheets function COUNTA, which will count the number of values in a dataset, and specify column A as the target, i.e. "=COUNTA(A:A)"
3.) now just request the value of cell B1 with gspread's acell, i.e. "last_row_updated = myWorksheet.acell("B1").value"
You can use the following code, taken from this answer to this similar question:
def last_filled_row(worksheet):
str_list = list(filter(None, worksheet.col_values(1)))
return len(str_list)

Linq to Excel ignoring header rows and using subheaders

I'm looking at Linq to Excel tutorials and they all seem pretty simple and straightforward excpet all of them assume the excel table being used has all column headers neatly placed on row 1 and starting at column A.
I need to query data from excel files where the tables not only start around row 6 (some may start at lower rows) and have headers and subheaders (headers represent a specific place/company; subheaders represent column values for that place like id, stock remaining, sales made, etc.).
Is there any way to specify for the query which row holds the headers I want to use so it only takes information from beneath them?
Can you just skip the number of rows you don't care about?
rows.Skip(1).Select(r => // Rest of your stuff here...
Better yet, query the appropriate range from the start like the LinqToExcel wiki suggests:
//Selects data within the B3 to G10 cell range
var indianaCompanies = from c in excel.WorksheetRange<Company>("B3", "G10")
where c.State == "IN"
select c;

How do i make a cell using variables? using VB script in Excel 2007

I am working on a project which requires me check for the last used row in the spreadsheet and then extract data from a range of cells from another spreadsheet after this last used row in a cell (i.e. A10 etc.)
The problem is that i know which column name from the current spreadsheet to use for importing data (i.e column A), but is there a way to assign the row number and make a cell which looks like "A". The last used keeps changing as the last row used keeps changing as we add data.
Here is the current code to maybe better explain myself:
LastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
CurrRow = LastRow + 1
ExtractExcelToArray wsDCCTabA.Range("C15:C25") ' Extracting from here
ExportAccesstoExcel wsTempGtoS.Range("E&CurrRow:E12") 'importing into current spreadsheet code here
As you can see, i tried using something like "E&CurrRow" but it doesnt seem to work. Any help is appreciated.
ExportAccesstoExcel wsTempGtoS.Range("E" & CurrRow & ":E12")

Resources