Is there a way to activate Autofilter only on specific columns in VBA? - vba

I have a macro that creates a separate workbook from a larger document. The number of columns vary on how much data is entered. I would like to add an autofilter to only the currently used columns but every time I add an autofilter I have to put in a range and the range varies. Is there a way to write in the code to only add the filter arrow on the applicable columns and not all of them that could possibly be shown? We are sending the document out to a customer and have to manually unfilter the blank boxes which we would prefer not to do.
Thanks!

Turn your data into an Excel Table using the Ctrl + T keyboard shortcut. These have the autofilter built in, and it automatically gets applied to any new columns in the Table, because Tables expand automatically to accommodate any new data.
Furthermore, because Tables are basically Named Ranges that Excel maintains on your behalf, it is very easy to identify the ranges concerned in VBA, as per my answer at VBA coding to identify and clear data in a specific table

Related

How to create a macro in word to import multiple tables from excel?

Frequently in my job I need to generate reports with lots of tables of inputs and results. Especially for the result tables, one change in analysis may require editing a dozen spreadsheets. I'd like to create a macro in word that pulls in data from a spreadsheet, with each table on it's own tab, so that if I update any of those tables in excel the word document tables will also update. Given the number of tables/data points, I don't want to have to tell the macro to pull each single data point. The aim would be to reduce time and errors from manual entry.
I'm thinking this would involve the following steps, but not sure how to go about them:
1) Define the name/size for each table in word with matching name/size in excel
2) Tell the macro to pull the data into a table format
I'm not sure if this is possible as so far I've only seen how to insert a caption or a text box, not insert or update entire tables. Any help would be greatly appreciated!
Depending on what you're doing, you may not even need any VBA code.
If you copy a range from Excel and paste it into Word using Paste Special with the 'paste link' option, any subsequent changes in the Excel range will automatically be reflected in the document when the workbook is saved. And, if you name the range in Excel before copying/pasting, the Word content will expend/contract to reflect changes in the named range's scope in Excel. A variety of paste formats is supported.
Alternatively, you might use a DATABASE field in Word.

Formatting Data in excel sheet with blue prism

I'm trying to run a duplicate check In which varying data is pulled from a website and compared to a master list, the master list being stored in Excel. The information from the website is read from a table in which has line breaks. These breaks are translated over to the data collection they are initially stored in. Some of the data from the website us eventually written to the master list in Excel. So when I read the master list back into Blue Prism to run a duplicate check, the rows that have line breaks are written into a collection as multiple rows (ex. I should have on 7 rows in my collections but am getting 42). Since the rows are not EXACTLY the same between the 2 collections, when it runs the automation does not recognize the duplicates.
The easiest way to solve this would be if I could make the collection rows have no line breaks as soon as the data is read. I've attempted to use the calculation stage to do so with no luck. I'm not sure if it is actually possible to do this, but would appreciate any direction.
Record an Excel macro to do the data sorting/cleaning in Excel (possibly Text To Columns, etc..) and then include the running of the macro as part of your Blue Prism process by using an action stage and the MS Excel VBO - Run Macro. Get the process to create an Excel instance (and create a handle data item from that stage), then use Open Workbook (whatever workbook you store your Macro in) and then use the MS Excel VBO - Run Macro (use the same handle created earlier and type in the name of the "macro").
It sounds like what is happening is that the MS Excel VBO is grabbing the data from the Excel Worksheet wholesale.
This is to say that it's accessing your Worksheet table, copying the cell values BUT not the cell formatting data, and then dumping the values into a BP collection.
Since it did not bring along any of the original cell formatting data to reference when it went to populate the collection it's just breaking up the values based on crturn/line breaks. Thus, your collection is organized based on that, and not on the original Worksheet cell.
So, with that said, on to a solution!
Solution 1
Brute force the organization of the incoming Excel cell data to the collection by looping over the Excel Worksheet cell-by-cell.
Run a loop, and in that loop have BP go into the Excel Worksheet and grab the first populated cell it comes across. Run a formatting/cleanup Calculation stage over the data. Dump the cell value into a single collection field.
Repeat.
This is...inelegant, expensive at best, and not at all recommended for any medium to large dataset. But it's definitely the best way to do string manipulation and value comparisons before it hits your collection. Since it sounds like your using a Master template then you as-well know what the expected format of your data should be.
This method will enable you implement Trim(), Concat(), or Split() in a Calculation stage to better organize your incoming data before you dump it into a collection.
This is also basically what I think you're already trying to do, but cell-by-cell instead of Worksheet row-by-row or table-by-table.
Solution 2
Clean up the table data you grab from the website before you dump it into the Excel Worksheet.
This is basically Solution 1, but in reverse. Simply format/cleanup your data before it hits you Excel Worksheet.
I'm not sure this is any better than Solution 1, but, you know, it's something...
Solution 3
Format the cell data IN the MS Excel Worksheet itself.
Basically rearrange the cells and cell data in the Excel Worksheet into a more predictable format by using the Split, Trim, Merge, or other actions included in the MS Excel VBO. You can also do this using the Data - OLEDB utility object, but that requires some pretty solid understanding of SQL syntax.
This would look like this using the MS Excel VBO:
Grab the Excel Worksheet data wholesale and dump into a collection
Count the rows/fields of the collection
Is that number consistent with the desired/expected format of your data?
If not, have the bot go back into the Excel Worksheet and reformat the cells by removing any carriage returns/line breaks/whatever else
Repeat.
However, I'm always reluctant to reformat any original source, as it's then hard to figure out what wrong and where it went wrong when you've changed the original structure of your data. So it's best to always make a copy of the Worksheet before you make any manipulation.
Unfortunately I don't have access to my BP environment at the moment or I'd provide you with the act object actions you'd need to do any of this, my bad. Once I do I'll update this answer.

Workaround for either my approach or the 256 character limit in Excel VBA

My problem is as follows, I have a workbook with (to begin with) 2 worksheets, the first (called WIP) acts as a form of data entry, each new occurrence of the BoM requires an insertion of 4 columns which happens to the left of the existing columns. At the same time a new worksheet is created based on a copy of the existing second worksheet (called FitOut) which pulls various bits of a data from the first worksheet based mainly upon the version of the BoM selected and the supplier referenced.
Of course adding new columns to the WIP sheet causes the functions, arrays and formulas in the sheets to automatically update, I had used a quick workaround by using some code to hold and then paste the new occurrences data into the worksheet which is created at the start of the macro, however the formulas have become slightly complex (due to the need to look for the previous 4 occurrences and return values based on specific cell locations) that the 256 character limit has been completely shot ( I think I'm over 800 on some bits).
I've very limited as to the layout of the WIP sheet, and the sheet needs to be fairly idiot proof (hence macros, buttons etc) but it needs to run well...
ANy and all suggestions/help would be much appreciated.
I have put an example of the formula I am trying to use, if it can be condensed further pleas let me know:
=IFERROR(IF($C$1='WIP'!$U$1,(INDEX('WIP'!$A$1:$X$2500,SMALL(IF('WIP'!$U$1:$U$2500=$A$1,ROW('WIP'!$U$1:$U$2500)),ROW(6:6)),COLUMN('WIP'!$C:$C))),(IF($C$1='WIP'!$X$1,(INDEX('WIP'!$A$1:$AA$2500,SMALL(IF('WIP'!$X$1:$X$2500=$A$1,ROW('WIP'!$X$1:$X$2500)),ROW(6:6)),COLUMN('WIP'!$C:$C))),(IF($C$1='WIP'!$AA$1,(INDEX('WIP'!$A$1:$AD$2500,SMALL(IF('WIP'!$AA$1:$AA$2500=$A$1,ROW('WIP'!$AA$1:$AA$2500)),ROW(6:6)),COLUMN('WIP'!$C:$C))),(INDEX('WIP'!$A$1:$AG$2500,SMALL(IF('WIP'!$AD$1:$AD$2500=$A$1,ROW('WIP'!$AD$1:$AD$2500)),ROW(7:7)),COLUMN('WIP'!$C:$C)))))))),"")

Display change in value of a cell in adjacent cell using excel VBA

I have a excel sheet that display's price on certain items in a column by looking up amazon API using excel vba. The price of may change overtime. So I am trying to display the difference in prices each time i run my macro, in a cell adjacent to the cell that displays price.
But I am not sure how to achieve this. Can any body guide me on how to achieve this?
This is just a sample, it must be adapted to your schema and data layout. Say the prices are stored in column A from A1 to A100. Say you already have a macro called RefreshData() that updates column A. In B1 enter:
=C1-A1
and copy down. This macro store the current values in column C before refreshing the data:
Sub DoUpdate()
Range("A1:A100").Copy Range("C1")
Call RefreshData
End Sub
Column B will display the price difference.
Something like this?
Let's say your data are in a range A2:A10
Dim rng as Range
Set rng = Range("A2:A10")
rng.Offset(0,1).Value = rng.Value
Run this before you run your original macro to store the values in an adjacent column before the values change. You may need to make the range dynamic, depending on your needs.
Without seeing you code, I cannot give a detailed answer. However, I ran across a similar problem once, not using Amazon API though, but a sharepoint connection.
If the amazon api is somewhat similar to the sharepoint stuff, I guess it refreshes cells when you click "update", or run the update sub. In that case you will have to either create an array to store the old prices in vba (very slow process), and then write them to your table, or create a separate tab where you store the item-lastPrice combination.
I ended up storing not only current price but all prices and the date/time of the price, to be able to see change over time.
For the copying of data itself using VBA, either of the above methods should work. In my initial code I used vba loops :-p, but copying using excel functionality is much faster.

How to extract specific tables from a MS-Word document using VBA?

VBA is a programming language so I'll assume this question is ok on SO.
What API calls and other techniques can I use, to extract specific tables from an MS-Word document?
I need to write a program which will open several Word documents, and look inside for tables which have a certain text in Row 1 Column 1, and output those tables to another file, preferrably as cells in an Excel spreadsheet.
Is this possible? How would you tackle this? Where to start?
Thanks
The Document.Tables collection contains all tables in a document.
Each Table in this collection has certain properties, such as .Rows, .Columns, or .Cell, which give access to a given row, a given column or a given cell.
The Table.Range.Copy method copies the given table to the clipboard.
The Worksheet.Paste method pastes the copied table into an Excel sheet, using the currently active cell as the insertion point.