I am trying to delete more than one column in my excel sheet.
For Each lvi In ListView1.Items
If lvi.Checked = True Then
arrayLetters = lvi.SubItems(1).Text & ":" & lvi.SubItems(1).Text & "," & arrayLetters
End If
Next
arrayLetters = arrayLetters.Substring(0, arrayLetters.Length - 1)
Dim rg As Excel.Range = xlSheet.Columns(arrayLetters)
rg.Select()
rg.Delete()
The value of arrayLetters is "G:G,F:F". For some reason that doesn't seem to work once it gets there to delete them! Only reason i am doing it this way is so that it doesn't update the table and loop to the other one. In other words, if i delete each one individually then the column moves and the letter will not be the same the next go around.
The error is on the Dim rg As Excel.Range = xlSheet.Columns(arrayLetters) line and it says:
Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))
Any help would be great!
David
SOLVED
For Each lvi In ListView1.Items
If lvi.Checked = False Then
arrayLetters = lvi.SubItems(2).Text & "," & arrayLetters 'Puts numbers in BACKWORDS
End If
Next
arrayLetters = arrayLetters.Substring(0, arrayLetters.Length - 1)
Dim theNumbers As String() = arrayLetters.Split(",")
Dim num As Integer = 0
xlApp.ScreenUpdating = False
For Each num In theNumbers
xlSheet.Columns(num).delete() 'Deletes columns in reverse order (7,5,4...)
Next
Just delete the lowest numbered column N number of times to reflect how many columns in a row you want to delete. It's better to go off of column numbers rather than letters when dealing with Excel programatically. If you need a code example, let me know and I'll post one.
Edit:
Here is a code example that does what you want:
xlSheet.Columns(i).delete
You want
xlSheet.Range(arrayLetters)
I reckon, that is Range, not Column.
I think the important part to realize (which I didn't initially) is that you have to use numbers for the columns not the letters.
Related
I have the following data set, which contains duplicates.
values:
2880CR-20.36KX53305DECOAK2015
F05572-CN48517OCTOAK2016
F05572-CN48517DECOAK2016
F05572-CN48517NOVOAK2015
F05572-CN48517NOVOAK2015(duplicate)
F05572-CN48517DECOAK2015
F05573-CN48517JANOAK2016
F05573-CN48517FEBOAK2016
F05573-CN48517JANOAK2015
F05573-CN48517FEBOAK2015
F05573-CN48517MAROAK2015
F05573-CN48517APROAK2015
F05573-CN48517APROAK2015(duplicate)
I am trying to create a macro that will look at the values in column A, from A2:A (count of rows in column), and return a list of the duplicate values contained in the string declared "strMyDupList". Basically, if there is atleast 1 duplicate, the msgbox will pop up and the new sheet created with the columns address and values and I am trying to list out all the values seperated my a comma VERTICALLY, instead of horizontally across the sheet. so like:
Address value
$A$5 F05572-CN48517NOVOAK2015
$A$13 F05573-CN48517APROAK2015
my code is :
If strMyDupList <> "" Then
MsgBox "The following entries have been used more than once:" & vbNewLine & strMyDupList
Worksheets.Add.name = name
Worksheets(name).Range("A1").Value = "Location"
Worksheets(name).Range("B1").Value = "Value"
' Worksheets(name).Range("A2:C2").Value = Split(strMyDupList, ",")
Worksheets(name).Range("B4:B6") = Split(Application.WorksheetFunction.Transpose(strMyDupList), ",")
The results are that I am able to get the values tranposed from horizontal to vertical, however, with this code, it is only returning the FIRST VALUE in the list of values in the string, so it's returning:
Address value
$A$5 F05572-CN48517NOVOAK2015
$A$5 F05572-CN48517NOVOAK2015 (should be F05573-CN48517APROAK2015)
I've seen the UBound with Resize could work but I have no idea how the syntax works or is used. Can someone assist?
Thank you
Here is a complete example of how to leave duplicates out of your information.
Essentially, it sorts all of your information. Therefore, when you sort you'll get the consecutive value which would be itself if it was a dupe.
It uses a .NET feature, System.Collections.ArrayList, that was in 2.0 & 3.5 so that has to be installed on your machine. Usually it already is but it may not be. You can turn it on through Programs & Features.
Sub StringArrayDupeChecker()
Dim var As Variant
Dim holder As String
Dim strMyList() As String
Dim myDupeData As Variant
Dim str As String
str = "one,two,three,three,three,four,five,five"
strMyList = Split(str, ",")
holder = ""
Set var = CreateObject("System.Collections.ArrayList")
Set myDupeData = CreateObject("System.Collections.ArrayList")
For Each i In strMyList
var.Add (i)
Next i
var.Sort
For Each j In var
If Not j = holder Then
'do your stuff
str = "notDupe"
Else
myDupeData.Add(j)
End If
holder = j
Next j
End Sub
I have block of code where I'm using a For... Next loop to go through an Excel sheet, and tell me if values entered in the text boxes were found or not. I've modified it to work if the values match. Yet, I'm receiving the Object/With Block variable not set error, and it confusing me. I've created the following:
Dim Value2Find_1 As String = txtMachNumber.Text 'Serial number value.
Dim Value2Find_2 As String = txtMachName.Text 'Machine name value.
Dim ReplaceWithValue1 As String = "" 'Replaces the serial number value if found in the sheet.
Dim ReplaceWithValue2 As String = "" 'Replaces the machine name value if found in the sheet.
Dim ReplaceWithValue3 As String = "" 'Replacement for the date-time in the Date Column.
Dim Range2Use_1 = xlWS.Range("A1:A4000") 'Range to span the A Column.
Dim Range2Use_2 = xlWS.Range("B1:B4000") 'Range to span the B Column.
Dim Range2Use_3 = xlWS.Range("F1:F4000") 'Range to span the F Column.
Dim xlCell_A = Range2Use_1.Find(txtMachNumber.Text) 'Looks up the searched serial value in A Column.
Dim xlCell_B = Range2Use_2.Find(txtMachName.Text) 'Looks up the searched machine value in B Column.
Dim LastRow = xlWS.Range("A4000").End(Excel.XlDirection.xlUp).Row + 1
Dim i As Integer
With xlWS
For i = 1 To LastRow
If Not (Value2Find_1 = txtMachNumber.Text And Value2Find_2 = txtMachName.Text) Then
MessageBox.Show("No value exists here...")
Else
Range2Use_1.Find(What:=Value2Find_1, MatchCase:=True)
Range2Use_2.Find(What:=Value2Find_2, MatchCase:=True)
MsgBox("Found both values: " & Value2Find_1 & " and " & Value2Find_2 & " on row " & xlCell_A.Row)
End If
Exit Sub
Next
End With
If my textbox entries are not in the sheet, the errors returns on the following line of code:
MsgBox("Found both values: " & Value2Find_1 & " and " & Value2Find_2 & " on row " & xlCell_A.Row)
I've narrowed it down to have something to do with the variable that returns the row number of the located textbox entries - xlCell_A. This is where I'm stuck, however. What do I need to set this as in order to avoid the Object/With Block variable not set error? I am afraid I don't know what this is asking for.
I think the problem with your code is that the Find method returns Nothing whenever no match is found, as stated in its documentation. Thus, xlCell_A.Row returns the error because the Row method cannot be called on Nothing.
Actually, I see a number of further issues with your code:
The interior of the for loop does not depend on the loop variable i. Hence, it does exactly the same thing in each interation.
The variable xlWS of the With block is never used, which makes the With block unnessesary.
The return values of the Find methods in the loop never gets assigned to anything. Because of this, they have no effect.
The condition in the if statement always returns False since you never change the values of Value2Find_1 and Value2Find_2 and you initialized them to txtMachNumber.Text and txtMachName.Text, respectively.
If you intend to evaluate whether the values txtMachNumber.Text and txtMachName.Text are present in the column A and B, respectively, you can just test whether xlCell_A and xlCell_B are Nothing.
Since you want to find both on the same row, which using Find does not guarantee, it might be easier to use a loop as in your code but replace
txtMachNumber.Text and txtMachName.Text with Range2Use_1.Cells(i,1) and Range2Use_2.Cells(i,1) in the if statement. (This compares the value in the ith row with the values to search for.) Obviously, you would have to exit the loop after finding a match, e.g. using the break statement.
I need to name my headers according to the items I have in a combo box. I'm basically taking the items from a combo box and adding them to the end of an existing header row in a excel sheet, so starting at the first empty cell in the headers row. However, I can't seem to move to the next cell to the right which would be the next header/column name. Here is my code thus far:
For i = 0 To ComboBox1.Items.Count - 1
Dim s As String
s = Convert.ToString(ComboBox1.Items(i))
xlWorkSheet.Range(columnName & "1").Value = s
Next i
ColumnName is the next blank header in that row, Column "L", so from there i would like to populate that cell then move to the right to the next cell.
As others have suggested, you can use Cells() to help iterate easier. Note that the user/macro needs the column number, not letter:
Edit: How's this instead:
Dim s As String
Dim myCol As Long
For i = 0 To ComboBox1.Items.Count - 1
myCol = Range(columnName & 1).Column
s = Convert.ToString(ComboBox1.Items(i))
xlWorksheet.Cells(1, myCol + i).Value = s
Next i
Loops are so yesterday :]
You can set all headers at once with something like:
Dim headers = ComboBox1.Items.Cast(Of Object).ToArray
xlWorkSheet.Range("A1").Resize(1, headers.Length).Value2 = headers
Also, when you get acceptable answer you should check the green check next to it https://stackoverflow.com/tour
This is what finally worked for me
Dim headers = ComboBox1.Items.Cast(Of Object).ToArray
xlWorkSheet.Range(columnName & "1").Resize(1, headers.Length).Value2 = headers
you can create a method that will get parameter of the column number
to start, use counter to point the column index.
if headers are not in row 1 so add another parameter of row and
replace xlWorksheet.Cells(1, counter) with
xlWorksheet.Cells(yourNewParameter, counter).
use short or integer data type not Long.
you dont need to create a variable for xlWorksheet.Cells(1,
counter)
make your code shorter.
code:
Private Sub AddHeaders(ByVal columnNumberToStart As Short)
Dim counter As Short = columnNumberToStart
For i = 0 To ComboBox1.Items.Count - 1
xlWorksheet.Cells(1, counter) = ComboBox1.Items(i).ToString()
counter += 1
Next
End Sub
This also worked:
For i = 0 To ComboBox1.Items.Count - 1
Dim s As String
myCol = xlWorkSheet.Range(columnName & 1).Column
s = Convert.ToString(ComboBox1.Items(i))
xlWorkSheet.Cells(1, myCol + i).Value = s
Next i
I have an extremely large dataset with customer numbers and we cannot just use a =IF(E3=160248, "YES", "NO") to tag a particular customer number of 160248 with YES or NO. Instead, I would like to use VBA code to lookup Customer_Number in column E and return a YES or NO in the corresponding row in Column AG, called Incorporated_160248. I have not done an If then clause in VBA, so I have no idea where to start. Please note, each month the data set can change. One month it could be 4,000 entries and the next 3,500, so that has to be dynamic. Any thoughts?
Sub TagTryco()
Dim CN As Integer, result As String
CN = Range("E:E").Value
If CN = 160248 Then
result = "YES"
Else
result = "NO"
End If
Range("AG:AG").Value = result
End Sub
I get a Compile error: Wrong number of arguments or invalid property assignment.
This CODE Works now:
Sub TagTryco()
Dim listLength
listLength = Worksheets("ILS_Import").Cells(Rows.Count, "E").End(xlUp).Row - 1
Dim i As Integer
For i = 2 To listLength + 2
If Worksheets("ILS_Import").Range("E" & i) = 160248 Then
Worksheets("ILS_Import").Range("AG" & i) = "Yes"
Else
Worksheets("ILS_Import").Range("AG" & i) = "No"
End If
Next
End Sub
To know how many entries you have:
dim listLength
listlength = Sheet1.Cells(Rows.Count, "E").End(xlUp).Row - 1 'I assumed column E, starting at row 2
You need to loop from row 2 to the row 2 + listLength, check the cell in column E, and check if it is equal to your number:
dim i as integer
for i = 2 to listLength + 2
If Range("E" & i) = 160248 Then
Range("AG" & i) = "Yes"
Else
Range("AG" & i) = "No"
End If
Next
If you wish to scan for different numbers you can adapt the code to use a value from a cell in which you enter that number, OR use an inputbox to enter the number you want to look for, or something else. This code was not tested.
If you want to use the column name you assigned instead of AG (which is safer) you can use something along the lines of:
= Range("Incorporated_160248")(i+1)
Instead, which gives the column with an offset of i. Should bring you to the right cell.
I have a dated CS degree so I understand the basics of VB but I don't write macros very often and need help solving a particular condition. (...but I understand functions and object oriented programming)
Assume the following:
- Column A contains reference ID's in alphanumeric form, sorted alphabetically.
- Column B contains strings of text, or blanks.
I'm trying to write a macro that automatically removes any extra rows for each unique reference number based on the contents of the "Notes" in column B. The problem is that if column A has multiple instances of a unique ref number, I need to identify which row contains something in column B. There is one catch: it is possible that the reference number has nothing in column B and should be retained.
To explain further, in the following screenshot I would need to:
Keep the yellow highlighted rows
Delete the remaining rows
I tried to show various configurations of how the report might show the data using the brackets on the right and marked in red. Its difficult to explain what I'm trying to do so I figured a picture would show what I need more clearly.
This task is making the report very manual and time consuming.
it's pretty simple
you just go throug the rows and check whether this row needs to be deleted, an earlier row with this id needs to be deleted or nothing should happen.
in my example i mark these rows and delete them in the end.
Sub foo()
Dim rngSelection As Range
Dim startingRow As Integer
Dim endRow As Integer
Dim idColumn As Integer
Dim noteColumn As Integer
Dim idValuableRow As New Dictionary
Dim deleteRows As New Collection
Set rngSelection = Selection
startingRow = rngSelection.Row
endRow = rngSelection.Rows.Count + startingRow - 1
idColumn = rngSelection.Column
noteColumn = idColumn + 1
For i = startingRow To endRow
currentID = Cells(i, idColumn)
If idValuableRow.Exists(currentID) Then
If Trim(idValuableRow(currentID)("note")) <> "" And Trim(Cells(i, noteColumn)) = "" Then
deleteRows.Add i
ElseIf idValuableRow(currentID)("note") = "" And Trim(Cells(i, noteColumn)) <> "" Then
deleteRows.Add idValuableRow(currentID)("row")
idValuableRow(currentID)("row") = i
idValuableRow(currentID)("note") = Cells(i, noteColumn)
End If
Else
Dim arr(2) As Variant
idValuableRow.Add currentID, New Dictionary
idValuableRow(currentID).Add "row", i
idValuableRow(currentID).Add "note", Cells(i, noteColumn)
End If
Next i
deletedRows = 0
For Each element In deleteRows
If element <> "" Then
Rows(element - deletedRows & ":" & element - deletedRows).Select
Selection.Delete Shift:=xlUp
deletedRows = deletedRows + 1
End If
Next element
End Sub
it could look something like this. the only thing you need is to add Microsoft Scripting Runtime in Tools/References