I am new to VBA and have been hacking together code from various examples and tutorials around the web. I'm aware that this will mean my code is hideous and inefficient, but I'm focusing on getting things to work right now and learning to clean up later.
I'm stuck on the part of my task that involves making an 'address manager' to store modifiable lists of recipients for daily email tasks. I created a userform to act as the manager, and it works fine to add files (user fills in textbox and clicks add, item is added to listbox and to relevant sheet in the workbook) and deletion works fine to a point (user selects item from listbox, clicks delete, item is removed from listbox and source sheet, and the list is repopulated.)
I can add and delete items freely, and the rest of my program interacts properly with the lists, but for some reason there's a weird problem I can't find the source of. When I created the file to test, I added 2 email addresses to each tab that contains a recipient list. I can add recipients and they show up perfectly, and I can also delete them without issue. The problem occurs when I try to delete one of the last two entries (regardless of what they are) I will get a Runtime Error 381 - Invalid Property Array index.
The debugger points me right at the starred part of the following code, which is the code I use to populate the list. It works fine as long as there are more than 2 entries for each. As soon as one of the last two entries are removed, the runtime error occurs and I can't even open the userform unless I go and manually add a second entry to the source sheet. I'm sure I`m missing something simple, but I really appreciate any help you may have.
Sub FillFS4ListBox()
Dim rng As Range
Me.MultiPage1(0).FS4listbox.Clear
With wb.Sheets("FS4")
Set rng = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
**Me.MultiPage1(0).FS4listbox.List = rng.Value**
End With
End Sub
Me.MultiPage1(0).FS4listbox.List = rng.Value
Using Value on a single-cell range doesn't produce an array, just a single value. If List expects an array then you'll need to check your input range to see if it's a single cell, then wrap that cell's value using (eg) Array()
E.g. - putting this in a function:
Function GetList(rng As Range)
GetList = IIf(rng.Count = 1, Array(rng.Value), rng.Value)
End Function
Usage:
Me.MultiPage1(0).FS4listbox.List = GetList(rng)
Related
Trying to delete, rather than hide from one worksheet (where the filter button is to another where the catalogue list is. i.e. trying to create something like (best way to describe this) a shopping basket based upon the users selection and reducing the (long) list on the other worksheet after selection.
I am beginning to pull my hair out on this one and after having read and watched many, many articles on deleting rows after filtering on empty cells and today nothing has really helped as there are more issues than solutions when following codes from other, thus far.
Basically, I have a Hugh catalogue on a separate worksheet and if the user says yes, this should be shown and if not if blank (but with a value) it should be deleted. See so very basic script I have that works perfectly, but I have to delete and not hide. It appears EntireRow.delete is something beyond me, as it introduces many many issues, where hide simply worked so smoothly.
Trying many other scripts, they all really fail in simplifying the answer and 99% are actually for a single worksheet and range rather than a specific worksheet and specific columns i.e. E:E (script script below shows more) I am using a table too, so this is a little different too.
For a = 2 To 150
If Worksheets("Requirements").Cells(a, 5).Value = "High" Then
Worksheets("Requirements").Rows(a).Hidden = True
End If
Next
Anyone with a brilliant one or two liner to delete rather than hide, or delete all hidden if necessary
Many thanks in advance
Consider:
Sub sjdhfs()
For a = 150 To 2 Step -1
If Worksheets("Requirements").Cells(a, 5).Value = "High" Then
Worksheets("Requirements").Cells(a, 5).EntireRow.Delete
End If
Next a
End Sub
Note we run the loop from the bottom to the top.
Context
I have developed a maintenance schedule for a production department in our company. As an extra addition we want to register which spare parts they use and how many. There are four machines in this department. Each machine has its own maintenance schedule made in Excel.
Description application
I have made a external central list which I open by Set myData = Workbooks.Open("Hyperlink"). This list contains all the spare parts for the machines. I have made this list external because the operators of the machine also need to be able to add extra parts.
I then populate a listbox with all the spare parts from the external list. When the listbox is populated I close down the external list, so that someone else can open the list. The image below shows what the userform looks like. The listbox is now filled with dummy products because I am still testing it.
The operators of the machine need to be able to select multiple spare parts.
Problem
I want the operators to be able to filter the listbox and at the same time select multiple spare parts. This is where it gets tricky.
I know how to filter a listbox, but my way resets the listbox each time which consequently makes it impossible to select multiple product. I have looked at some other topic on stack overflow, but they have the same problem.
Question
Is there a way I can filter the listbox, select an item, filter again, select another item, filter again, select again another item etc. etc. ?
*Filter the populated listbox without having the source sheet open
Thank you in advance.
This topic needs the list to remain open and resets the listbox eache time
This topic deletes all the items from the listbox
With help of #JvdV I solved part of the problem. His solution makes sure that I can select some products and save that selection. This enabled me to add some code for a textbox that filters the listbox. This code filters the populated listbox by deleting all the contents that dont equal the textbox.
When the textbox is emptied to "" the listbox is reset and populated again. See the whole code below;
Private Sub FilterProdNr_Change()
For i = UsedPart.ListCount - 1 To 0 Step -1
If InStr(1, UsedPart.List(i), FilterProdNr) = 0 Then UsedPart.RemoveItem (i)
Next i
If FilterProdNr = "" Then
UsedPart.Clear
Dim myData As Workbook
Dim cProd As Range
Dim ws As Worksheet
Set myData = Workbooks.Open("Hyperlink")
Set ws = Worksheets("OnderhoudPartsCentraal")
For Each cProd In ws.Range("Product_nummer")
With Me.UsedPart
.AddItem cProd.Value & " <> " & cProd.Offset(0, 1).Value
End With
Next cProd
myData.Close
End If
End Sub
I have a bug in my excel sheet that appears on other computers I can't reproduce on my machine.
I made a sub that takes data from a database and create tables in Excel. In this case it's mining projects.
It picks the first cell, finds the first empty cell when going to the right, writes the header, makes a table with it then fill it with another sub.
When a coworker tries to use it, it extends the previous table then crashes while trying to make the new one, as two tables can't overlap.
Initial Layout:
What's supposed to happen:
What my coworkers get:
Public Sub creerTable(Nom As Variant)
Dim cellule As Range
' se placer
Set cellule = ActiveWorkbook.Worksheets("DATA").Range("A1").End(xlToRight).Offset(0, 1)
Do While cellule.Value <> "" Or Not IsEmpty(cellule)
Set cellule = cellule.Offset(0, 1)
Loop
'cr?er le header
cellule.Interior.Color = vbBlue
cellule.Value = Nom
'cr?er la table
ActiveSheet.ListObjects.Add(xlSrcRange, cellule, , xlYes).Name = Nom
End Sub
EDIT: After more testing on my coworkers' computers, the problem is likely linked to an Excel setting. When something is written to the right of a table, the table extends to cover it. Googling revealed this to be an auto-correct behavior. I guess I'll have to deactivate that option of auto-correct.
The answer was really dumb. The problem is an autocorrect setting in excel. All I had to do was add this line:
Application.autocorrect.AutoExpandListRange = False
It's not clear how this code could possibly work on your machine, but not your co-workers. I suspect that the inputs must somehow be different, but that is for you (having access to the inputs, which we do not) to work out on your own. Generally: inconsistencies cannot exist, so when one appears to exist, examine your inputs and you'll usually find there is a discrepancy in the input data which causes the divergent output.
I'll note that The End method of range objects may not be reliable, in particular I observed things like Range("A1").End(xlToRight).Address yields "B1" in the following scenario where column A, B and C are each separate ListObject tables:
And ALSO in this scenario:
It seems like you try to find the next empty cell/column (which may be between two or more non-empty cell/column). It should be trivial to do this, but we need to understand that next is relative to what existing thing on your worksheet?
Are you're trying to find the next empty cell after a ListObject named "Tâches" (or cell value = "Tâches")?
Sub TEST()
If cells(i, "R").Value <> "UK" Then
cells(i, "R").Interior.ColorIndex = 3
End If
End Sub
If I run this program it throws application defined error \
I am new to Excel (beginner)
How to correct this error!!!
Thanks In advance
I think the issue is "R" that I know of the cells method takes 2 parameters one is rows the other is columns (in that order) but this is done by number not letter so if you change it to cell(1,18) then the code above works fine.
This link may also be useful to learn more, among other things it describes how you would normally select a range first as I believe your code above will assume the currently selected page, however you might want to run in on a button click from another page or as soon as the spreadsheet opens.
http://msdn.microsoft.com/en-us/library/office/ff196273.aspx
The problem is that the variable i has not been assigned a value. VBA assumes that it is zero. Since i is used to determine the row of the cell, Excel throws an exception because there is no row 0!
First you have to define i variable
for example: Dim i as variant
I am creating a form in excel (not a userform) and I am populating the listbox using cells. However, these cells are sometimes A1:10 and sometimes they are A1:A4. Is there a way to dynamically change what is shown in the listbox?
Right now, when I use A1:10 and there are only 4 cells populated, I get the list of 4 populated cells followed by 6 blank entries. I'd like to get rid of the 6 blanks when there are only 4.
Unfortunately, this is more of a workaround than a solution. However, it may be able to do what you need it to do. I've been hitting the same wall you are with trying to make ranges dynamic.
Without seeing some code to know exactly what you're doing, try something like this.
Private Sub ListBox1()
x = 1
'Add items to listbox until you reach an empty cell.
Do while Cells(x,1) <> ""
ListBox1.AddItem Cells(x,1)
Loop
I'm not very familiar with listboxes outside of userforms but this should do approximately what you want to do.
Edit your original post with your code so we can try and get a better understanding of what you've tried and what you're trying to do.
You can create a named range using a dynamic formula. Either of the below formulas will work.
=A1:INDEX($A$1:$A$10,MATCH("",$A$1:$A$10,0)-1)
=OFFSET($J$7,0,0,MATCH("",$J$7:$J$32,0)-1)
To create the named range, click ctrl+F3 then click new, insert one of the two options above into the "refers to:" section, then label the new range whatever you would like. in the "row source" section of the listbox simply type in the name you selected for your new named range.