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")?
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.
I have a userform that is supposed to insert a row on Sheet3 and populate some cells in that row with some values. it works great as long as I have sheet3 displayed. (The form is shown modeless to give me access to the sheets).
Anyway, I happened to have another sheet active and ran it again and was surprised to see it inserted the row not in sheet3, but in the one I had displayed... (Thank God I saved first!)
In the code, I specified a range object as follows to find the insertion point: (I'll truncate the code a bit to keep it simple)
Dim RecordRange As Range
Set RecordRange = Sheet3.Cells(RowVariable,ColumnVariable)
RecordRange.Offset(1,0).EntireRow.Insert
blah blah blah.
A workaround is to activate the sheet first:
Sheet3.Activate
That at least inserts into the correct sheet, but I'd rather not have sheet3 be displayed when I add the record, so I even surrounded that line with:
Application.ScreenUpdating = False
Sheet3.Activate
Application.ScreenUpdating = True
unfortunately, ScreenUpdating doesn't work from within a Userform Code module, so that bites...
I still don't understand why it chooses to insert the row into whatever sheet is active, when I've already specified sheet3 in the code. I have another Macro very similar that doesn't have this problem.
any ideas?
...so you figure your workaround needs a workaround? Hmm... I think that qualifies as a double-negative since a workaround is supposed to, by definition, fix problems rather than cause them...
A workaround is a bypass of a recognized problem in a system. A
workaround is typically a temporary fix that implies that a genuine
solution to the problem is needed. But workarounds are frequently as
creative as true solutions, involving outside the box thinking in
their creation.
Typically they are considered brittle in that they will not respond
well to further pressure from a system beyond the original design. In
implementing a workaround it is important to flag the change so as to
later implement a proper solution.
Placing pressure on a workaround may result in later system failures.
For example, in computer programming workarounds are often used to
address a problem or anti-pattern in a library, such as an incorrect
return value. When the library is changed, the workaround may break
the overall program functionality, effectively becoming an
anti-pattern, since it may expect the older, wrong behaviour from the
library. (Wikipedia)
Just sayin'... :-)
So instead of fixing the workaround, your original issue is (thankfully) straightforward.
You're using Sheet3 as an object, and I suspect you haven't assigned anything (like Worksheets("Sheet3") to an object called Sheet3.
Try this instead:
Dim RecordRange As Range
Set RecordRange = Worksheets("Sheet3").Cells(RowVariable,ColumnVariable)
RecordRange.Offset(1,0).EntireRow.Insert
If you indeed intended to use Sheet3 as an object then make sure it's declared as set, so for example you could instead use:
Dim RecordRange As Range
Dim Sheet3 As Worksheet
Set Sheet3 = Worksheets("Sheet3")
Set RecordRange = Sheet3.Cells(RowVariable,ColumnVariable)
RecordRange.Offset(1, 0).EntireRow.Insert
Also, just to point out: If either of these solves your issue then the problem would've "made itself known", by including one line at the top of every module (at least during development & troubleshooting):
Option Explicit
This link has a short explanation, but basically it forces you to properly declare all variables (thus helping to prevent future workarounds!)
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)
I got stuck at a problem with Excel VBA.
I am supposed to do the kinda easy task of copy/paste a variable range of cells from "sheet2" into the same range in "sheet1".
500 Rows like in my code is far too much, but I tried it this way, to "catch" the variable aspect.
The tricky part is, that the range in "sheet1" is a table(which gets created from TFS).
Sub CopyP()
Sheets("Sheet1").Range("B3:F500").Value = Sheets("Sheet2").Range("B3:F500").Value
SheetObject.ListObjects (ListObjectName)
Range("NAME OF TABLE[Iteration Path]").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
The [Iteration Path] is a column name of my table, i want to check in this column/with this parameter, if the "row" is empty.
I know the code is far from being good or clean but the table is giving me a hard time copying.
With this code I got another problem: the table gets created from TFS, no problem to copy into that, BUT the name of the table is variable(seems like TFS creates the name), so unless I put the name manually in the code, the "program" cant execute, because of missing range.
Didn't find a way to get a return of the table name somehow.
But I think I am just following the wrong path overall, maybe someone can be bring me on the right track.
My other Idea is to Iterate through the Rows in Sheet 2 to fetch just as much data is needed and then copy them with an iteration into the table. But i guess I would be the same problem with the table-name there.
Every information I find using google , talks about tables where the user can "name" the table. In my case I cant, so I have to work with the name TFS uses for my table.
Further to my comments below your question, I just typed this in notepad. Please amend it to suit your need.
This will give you the names of all tables in the activesheet. If there are multiple tables then you will get multiple names. (UNTESTED AS POSTING FROM PHONE)
Sub sample()
Dim objLB As ListObject, TableName As String
For Each objLB In ActiveSheet.ListObjects
TableName = objLB.Name
Exit For
Next
Range(TableName & "[Iteration Path]").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
I am an old man trying to compare dates from two different files in Excel.
My code is:
Dim i As Integer
For i = 1 To 7
IF Data_for_Processing.xls (“SOLARLOG”). Cells (i,”A”).Value = Day_Conversion_chart.xls (Sheet1).Cells (i+2, “B”) Then
Cells(7+I, “B”)=”Equal”
Else: Cells(7+i, “B”) = “NotEQ”
End If
Next i
Will anyone help?
First of all, I would recommend following #simoco 's advice - Reading the documentation will provide the tools for solving future problems and give you the basics. As well as that, I would recommend using vba help. And another very useful tool for trying commands could be recording macros and analyzing them later on the editor.
So, first you need the code to be inside a macro. It will look like this (I chose the name TestMacro):
Sub TestMacro()
'Code here.
End sub
You should take into account that when your macro is running, it does so from the sheet you are working in, so any partial references to cells, etc. will refer to the book you are in and the sheet you are in when you run the macro. It is possible to select another sheet or book, and if you do so manually or on the code, references will be applied on that selected book or sheet.
What I call partial references here are those that read simply "ThisCell" instead of "ThisBook.ThisSheet.ThisCell". I would say that using partial references, though, is appropriate in a vast majority of cases.
The way your code is organized, be careful to run it from the workbook where you want the data to be in the end, let's say, in your 'main' workbook, so that the final values will be written there..
Another comment: whenever you want to use another file, this file must be open (as far as I know), while you are using it. In your code, you don't open any file, so the macro will not work if you don't open ALL referenced workbooks manually prior to running the macro.
When you want to reference something inside something, you mostly use ".". Please read the documentation - You will get a better idea of how this works. For this example:
Book.Sheet.Cell.Value is the structure you are using.
A book can be referenced as Workbooks("Name.xls") if it is open.
A sheet or worksheet can be referenced as Sheets("Name") or Worksheets("Name"), and also with numbers, like Sheets(1) or Worksheets(1). The differences can be seen on vba editor help. I chose Sheets(...) for your example.
Be careful with the symbols. I guess this was probably my problem, but I have to mention it just in case: When I copied your code, instead of double quotes (""), I got something different, that Excel would not recognize. If for any reason you are using different symbols, Excel might not understand.
A cell can be referenced in various ways too. The Range object is used extensively, and if you want to use "A1", "C44", etc., it's probably better to go for it. I like using Cells(,) as you did, when possible. As far as I know, this works nice with numbers (Cells(1,2), for example), which may be very convenient too. I kept this on your code, changing "A" and "B" and writing 1 and 2, respectively.
With all these changes incorporated:
Comments:
'NOTICE THAT ALL WORKBOOKS MUST BE OPEN.
'["A"] changed to [1]
'[Sheet1] changed to [1]
'["B"] changed to [2]
'Data_for_Processing.xls(“SOLARLOG”).Cells(i, 1).Value
'becomes Workbooks("Data_for_Processing.xls").Sheets(“SOLARLOG”).Cells(i,1).Value
'Day_Conversion_chart.xls(1).Cells(i + 2, 2).Value
'becomes Workbooks("Day_Conversion_chart.xls").Sheets(1).Cells(i+2,2).Value
'["B"] changed to [2]
And one possible solution:
Sub TestMacro()
Dim i As Integer
For i = 1 To 7
If Workbooks("Data_for_Processing.xls").Sheets("SOLARLOG").Cells(i, 1).Value _
= Workbooks("Day_Conversion_chart.xls").Sheets(1).Cells(i + 2, 2).Value Then
Cells(7 + i, 2) = "Equal"
Else: Cells(7 + i, 2) = "NotEQ"
End If
Next i
End Sub
This worked on my Excel example - I hope it is of some help.
Regards.