I want to read an Excel file in the way that only used rows has to be taken out i.e if the excel file contains 47 rows initially but only 10 rows are filled then that 10 rows data has to be read(Don't want to mention it like A2C7 while reading,need to do it by default) Is it possible to achieve in VB 6.0.Kindly help me to solve this.
Used Range Property has worked for me,but now i found another problem While using this method ,if i add a value in a row after the last used row and remove the value at once and saves the file , it is showing the wrong usedRange value (i.e) it is showing the address of the row where i added and removed the value at once.how to handle this?
Try reading in the loop till the row is non empty (used). You can get used rows count by the following syntax:
<workbookname>.Sheets("<SheetName>").UsedRange.Rows.Count
for example
Workbook1.Sheets("Sheet1").UsedRange.Rows.Count
Related
The entire workbook is a few sheets long, however essentially I'm working with a base sheet that has around 8000 or so lines data with about 10 columns or so. The end goal of this project is to be able to input a start date, end date and a keyword and then be filtered one last time with another keyword. So far, I've been able to filter down the original data within the date range and within the first keyword. The problem arises now when the keyword is within a block of text that varies and is never quite the same. For example, one row contains
12T Q1FY23 Unscheduled/Emergency Maintenance
While another row contains
12T Q4FY23 ERT Spill Stations
There are hundreds of variations of this, but there, including ones that don't start with "12T". The starting data is subject to change so I can't quite use tables in excel and filter it that way, as once you apply a filter then the table won't update if new data is input as the source data, unless there is a way to do this and I just don't know how. So ultimately, I need the same filter that can be used on a table that says "contains" and/or "does not contain" as formulas. Formulas seem to work well with this dynamically/subject-to-change source data, so I'd like to keep it with formulas, as I have done with the filtering previously with the date range and then with the other keyword. The difference between what I want now and what I did for that other keyword is that it was a static keyword that isn't embedded within a string like the "12T". Please let me know if this is too vague or if there's any more material needed to help answer this question. Attached is a sample image of a what I'm working with on the original sheet. I'd like to be able to extract the rows containing only "12T", and not the one's "12T-M", for example, using only a formula. Assume that the data starts at A3 and ends at C8. I should also mention, just to be completely clear, I'm trying to copy these rows dynamically into another sheet so that it can be nicely viewed with only the relevant information and data.
To be extra clear, I first filter it the original data with the following formula:
=INDEX(Sheet1!$A$6:$N$6796, SMALL(IF(COUNTIF('12T'!$H$11,Sheet1!$G$6:$G$6796), MATCH(ROW(Sheet1!$A$6:$N$6796),ROW(Sheet1!$A$6:$N$6796)), ""), ROWS(B3:$B$3)), COLUMNS(Sheet1!$A$6:A6))
The "Sheet1" referral contains the original data and "12T" refers to the sheet that contains the filtering keywords (the dates and the number keyword). This formula extracts all of the rows of the original dataset in Sheet1 that contain a specific keyword, in this case its "5351 - Facilities: Maintenance: Building". These extracted rows of data are deposited as an array (Entered with ctrl+shift+enter) in a new sheet labeled "Xtract".
In this same sheet, I then filter out this array with the date range in mind. With the starting and ending date, I first calculate the number of instances that a date falls within the date range with the following formula.
=SUMPRODUCT(($A$2:$A$671>=Q2)*($A$2:$A$671<=Q3))
I use this result in the following formula in conjunction with the filtered data (filtered with the previous keyword) to filter it further so that I only get the rows of data that have their date in the date range.
=FILTER(A2:O671,(A2:A671>=Q2)*(A2:A671<=Q3),"No data")
This is also entered as an array, and is also in the "Xtract" sheet. With this filtered data set, I want to filter it one last time, so that only the rows of data that contain, for example, "12T" or "728M" in one of the cells (in which the respective cell can be written as "12T Q1FY23 UEM") can get extracted and placed into a final array. All of this is automatically updated simply by entering the values in this section I have shown below.
I can't use a table to filter the data, at least not that I know of, because if I filter a table by this logic ("contains '12T'" and "does not contain '-M'" to get only rows that contain 12T but not 12T-M or anything that's not 12T) then once I change the date range or the other keyword, the table won't update properly. If there's anything else I can add to help clarify, please let me know.
Add a column to the left containing formulae: "=find("12T ",B1) and copy down.
Note the space after T.
Rows matching that will have 1; rows not matching will have #VALUE! so you can sort on them.
P.S. if #VALUE! is ugly, you can use =NOT(ISERROR(FIND("12T ",B2)))
After a lot of searching and referencing my old work/internet, I found the formula to answer my problem. I understand this might not be the most clear since I can't quite provide the excel workbook I'm working with, but the goal of this was to automate all of the filtering so that no matter if data is added or not, when you change the filters, it will stay updated correctly. From the filtered data that I had already worked with, all I had to do to put it into another sheet was use the following formula:
=FILTER(XtractFilters!T2:AF900,ISNUMBER(SEARCH("12T *",XtractFilters!T2:T900)))
This finds all of the data containing a specific substring, which in this case specifically was "12T ", denoting the space as well. So all of the filtered results are then filtered once again so that only the rows where "12T " was found get returned. The range is just the entire range of data and then the column is the one containing the text where "12T " could be found.
I'm stuck on an Excel problem and am hoping someone can assist. I read through 10-15 topics that are similar, but I wasn't able to get anything to work. Here is where I'm at...
I have a large data set containing columns for Year, Name, Total 1, Total 2 (and 20+ other columns). The same names appear in multiple rows based on the yearly totals. On a separate sheet, I have another data set containing Name and would like to pull the data from sheet one into columns as shown below.
I have done this in the past using only one year as the initial data set with the following formula:
=INDEX(DATARANGE,MATCH([#Name],DATARANGE[Name],0),MATCH("Total 1",DATARANGE[#Headers],0))
The problem I am having is the result of adding multiple years of data to my 1st data set. Is there a way to match the row based on name and year and then return the results of the appropriate column?
=SUM(($A$2:$A$9=B$16)*($B$2:$B$9=$A17)*($C$2:$C$9))
Enter above in cell B14 as an array formula or below as standard
=SUMPRODUCT(($A$2:$A$9=B$16)*($B$2:$B$9=$A17)*($C$2:$C$9))
You can do the same for total 2 just replace Cs with Ds
And then drag right and down.
Change the first MATCH function to something like this:
=MATCH(1,INDEX(([#Name]=DATARANGE[Name])*([#Year]=DATARANGE[Year]),0),0)
so as part of your whole formula that would be this
=INDEX(DATARANGE,MATCH(1,INDEX(([#Name]=DATARANGE[Name])*([#Year]=DATARANGE[Year]),0),0)
,MATCH("Total 1",DATARANGE[#Headers],0))
Another way you can use for returning numbers only (as here) is like this: (with cell refs for simplicity).
=SUMPRODUCT((A2:A9=2013)*(B2:B9="name x")*(C1:D1="Total 1"),C2:D9)
If the presented data to be indexed is a table then
This
=MATCH(1,INDEX(([#Name]=DATARANGE[Name])*([#Year]=DATARANGE[Year]),0),0)
should be corrected to a proper structured reference of
#[Name]
Also since this is an array formula it may not work with structured references at all. You'd be better served with regular cell references. Also if it is not a table only cell references will work.
I am using Excel::Writer::XLSX to create an Excel file from an array of arrays. Right now I'm trying to create a formatted table from the data (as much as I can, as opposed to just spitting it back into another file).
First off, when I use set_column() to set the background color, that color is formatted for the entire column. Is there a way to specify to only go as far as the content in the file goes? Unfortunately, when the program is run it is dynamic each time and unknown what the final row in the table should be.
Second, is there a way to merge cells based on the content inside of them? This has to do with the dynamic problem again, there is an optimal output if all the data I am gathering is online. If that were the case I could easily set a range of what these merged cells should be. But for example, if I have 10 rows of column 2 saying 'A' and then 10 rows of column 2 saying 'B', I would like to merge the A's and B's together. The issue is that is is unknown if it will always have 10 rows with that value inside of it.
Thanks for your input!
First off, when I use set_column() to set the background color, that color is formatted for the entire column. Is there a way to specify to only go as far as the content in the file goes?
No. You will have to have to add the format to the cells as you write them.
But for example, if I have 10 rows of column 2 saying 'A' and then 10 rows of column 2 saying 'B', I would like to merge the A's and B's together.
This isn't possible with Excel::Writer::XLSX. (In fact I don't think it is possible in Excel without using macros).
Since both of your issues relate to not knowing the size and value of the data beforehand then perhaps you could first read your data into an array of arrays, process it to find the required format dimensions and merge ranges and then write them out.
I have a spreadsheet where Iam trying to add the serial numbers in each row using the below formula
=IF(C149<>"";MAX($B$149:OFFSET(B150;-1;0))+0.1;"")
However, whenever I delete the rows in B column there will be error value in all other rows like #N/A
Whether it is possible to delete the rows without affecting the Formula ?
I heard there is a excel function "INDEX" to be used, please reply with your answers how to apply INDEX function to the above Formula
Not exactly the answer you were asking for, but google picks this out for deleting without breaking formaulas - so anyone landing here from google...
The formulas break because you are removing cells from the spreadsheet - chainging the structure of the sheet. Where as what you want to do is just remove the data, and have all the remaining data move up.
One way is to select all the data below the line you want cleared (plus one blank line at the end) - then copy that range (to the clipboard) and paste it all back in one row higher.
Not a great solution - but it works - I found this question looking for a better way! :)
The issue could be related to $B$149 When you delete a row the $ means that the 149 cannot change accordingly like the C149 and B150 would , this may then mean that it is pointing to incorrect data after the deletion.
I have had this problem forever and never managed to figure it out.
I am importing an excel (.xls) file into an asp recordset. Most of the time this works great.
I have column with the following values
4
4
5,6
3
Asp reads those values in except for the 5,6. I have tried formatting the cells and this makes no difference. It appears that asp (or excel) are trying to determine the type of the cell by examining the value. For whatever reason it then throws this hiccup if some of the cells aren't the same format as the majority of the other are.
The problem is that ADO scans the first 8 rows and based on the data it finds in each column it sets the column type. So if your first 8 rows contain numbers then it sets that column to numeric and returns null for any other values, for example if the ninth row contains text or a comma. See http://blog.lab49.com/archives/196 for some suggestions on how to avoid this.
Have you tried setting the 5,6 to 5.6?
Try adding IMEX=1 to your connection string.
If that doesn't fix it, then try changing the following registry key value:
HKLM/Software/Microsoft/Jet/4.0/Engines/Excel/
"TypeGuessRows"=dword:00000000
If you have a 64-bit system the registry key will be at:
HKLM/Software/Wow6432node/Microsoft/Jet/4.0/Engines/Excel/
"TypeGuessRows"=dword:00000000