VBA:Iterate through all columns of a worksheet - vba

Within the worksheet that the macro is defined in, id like to iterate through all the columns and save the ones that are filled in an array.
x = IIf(WorksheetFunction.CountA(Columns("C")) > 0, 1, 0)
This is an example of how I'd check if the column is empty. It returns 1 if the column is filled and 0 if it is empty.
Another thing that I'd like to know is how I could give and get the column name as a variable rather than hardcoded string ("C" as you see above).
Id like the array to look like:
("A", "B", "C", "E", "G", "H", "I")

This code should do the trick:
Dim DataCols() As String
Dim strTemp As String
Dim strCol As String
Dim i As Long
For i = 1 To ActiveSheet.UsedRange.Columns.Count
If WorksheetFunction.CountA(Columns(i)) > 0 Then
strCol = Columns(i).Address
strTemp = strTemp & Mid(strCol, 2, InStr(strCol, ":") - 2) & "|"
End If
Next i
strTemp = Left(strTemp, Len(strTemp) - 1) 'Trim trailing |
DataCols = Split(strTemp, "|")
The For..Next loop iterates through all columns in the active worksheet.
Using WorksheetFunction.CountA as you also used in your example it is then determined whether the current column has any data in it.
If the column contains data we get its address (Which will be a string in the format $A:$A) and use Mid(..) to get the letters between the $ character and the : character.
Append that column letter to strTemp, followed by a Pipe | which we will later use as a delimiter.
The Dynamic Array DataCols is then populated by using the Split function on strTemp to return a string array (delimited by the |s we included).
Hope this helps!

Related

ppt vba multiple slide selection macro error

When multiple PowerPoint slide numbers are entered in the input box (ex: 3, 5, 6), I want to create a macro that selects the slides of the entered number, but an error occurs.
Sub test()
Dim strresponse2 As String
Dim iresponse2 As String
strresponse2 = InputBox("page number" & vbCr & "ex) 2,4,11,5")
If IsNumeric(strresponse2) Then
iresponse2 = strresponse2
End If
ActiveWindow.Selection.Unselect
ActivePresentation.slides.Range(Array(iresponse2)).Select
'error here
'How to fix it so it doesn't get an error
'ActivePresentation.Slides.Range(Array(2, 4, 11,5)).Select
'no error
End Sub
Several issues here.
a) If you enter 2, 4, 5, the check for IsNumeric(strresponse2) will fail because the function tries to convert the whole string into one single number.
b) Array(iresponse2) will not convert the string into an array (of 3 numbers). It will convert the single string 2, 4, 5 into an string array with 1 (not 3) member.
In your case, you can use the Split-function to split the input string into an array of strings.
c) If you want to access the slides by number, the input needs to be of a numeric type, not of string (even if the strings contain numbers). You will need to convert the string array into a numeric array (if you pass a string or an array of strings as parameter, VBA will look for members with the name, not the index).
Have a look to the following piece of code and check if it does what you need - it's only half tested (as I have no Powerpoint VBA available, only Excel, but the priniple is the same)
Dim answer As String
answer = InputBox("page number" & vbCr & "ex) 2,4,11,5")
Dim pagesS() As String
pagesS = Split(answer, ",") ' Split the answer into an array of strings.
ReDim pagesN(0 To UBound(pagesS)) As Long ' Create an empty numeric array
Dim countS As Long, countN As Long
For countS = 0 To UBound(pagesS) ' Loop over all strings
If IsNumeric(pagesS(countS)) Then ' String is Numeric
Dim pageNo As Long
pageNo = Val(pagesS(countS)) ' Convert string to number
If pageNo > 0 And pageNo <= ActivePresentation.slides.Count Then
pagesN(countN) = pageNo ' When number is within valid range, copy it
countN = countN + 1 ' Count the number of valid page numbers
End If
End If
Next countS
If countN > 0 Then ' At least one number found
ReDim Preserve pagesN(0 To countN - 1) ' Get rid of unused elements
ActivePresentation.Slides.Range(pagesN).Select
End If

Assign value to a range with a variable column refreence

The following code gives me a compile error:expected: separator or ).
Public Sub test1()
Dim first_column As String,a_tab as string
a_tab="Sheet1"
first_column = "A"
ThisWorkbook.Sheets(a_tab).Range(first_column&"10").value="hello"
End Sub
I know we can do it when the row reference is a variable, i.e.
Public Sub test1()
dim fist_row as integer, a_tab as string
a_tab="Sheet1"
first_row=10
ThisWorkbook.Sheets(a_tab).Range("A"&first_row).value="hello"
End Sub
Could someone help? Many thanks.
Get out of the habit of using a letter for the column designation.
Your first column is column 1:
Columns(1).Value = "Hello" will place "Hello" in every cell in column 1 - Range(A1:A1048576).
The second cell in column 1:
Cells(2, 1) = "Hello" will place "Hello" in row 2, column 1 - Range(A2).
A range of cells designated by a start and end cell:
Range(Cells(2, 1), Cells(4, 2)) = "Hello" will place "Hello" in every cell between row 2, column 1 and row 4, column 2 - Range("A2:B4")
The first, second, third & fourth columns:
Range(Cells(1,1),Cells(1,4)).EntireColumn - Range("A:D").
But, saying that the only thing that caused your code to fail was spacing. You'll notice with the row variable it keeps putting the spaces back in - doesn't seem to do that with the column variable:
ThisWorkbook.Sheets(a_tab).Range(first_column & "10").Value = "hello"
- add a space either side of the ampersand.
Edit:
Consider placing values in columns CB:CL using a loop. Using numbers you'd just write:
Sub Test()
Dim x As Long
For x = 80 To 90
Cells(1, x) = "Hello"
Next x
End Sub
Using letters you'd have to use something like:
Sub Test()
Dim col_Letter As String
col_Letter = "CB"
Do
Range(col_Letter & "10") = "Hello"
'Get the next column letter by finding the address, splitting it and extracting just the column letter.
col_Letter = Split(Range(col_Letter & "10").Offset(, 1).Address(True, False), "$")(0)
Loop While col_Letter <> "CL"
End Sub
Are you missing spaces when concatenating strings in your argument to Range? ThisWorkbook.Sheets(a_tab).Range(first_column & "10").value="hello" Works for me if I add the spaces.

VBA excel: How do I compare a string array to a string?

I have a script that takes the contents of a cell, and puts the first 2 characters of the cell into a string array. I need to later compare that string array to a string, but I can't seem to get that to work. Here's what I have:
For i = 2 To 600
colStr = Sheets("smartlist").Cells(i, "A").Value
If colStr <> "" Then
ReDim charArray(Len(colStr) - 1)
For j = 1 To Len(colStr)
charArray(j - 1) = Mid$(colStr, j, 1)
Next
strArray = LCase(charArray(0)) & LCase(charArray(1))
If CStr(Join(strArray)) = CStr(Join(pwArray)) Then
Now, I've tried:
If charArray = "ab"
If Join(charArray) = "ab"
If CStr(Join(charArray)) = "ab"
I'm pretty lost at this point. Any suggestions would be welcome!
Edit: added the whole function up until I get the 'Type mismatch'
You could use Join(charArray, "") - without "" it joins the elements with space so the result of your initial try was "a b"
Firstly, you really need to clarify what you're doing. You say that later you need to check what's in the string. If that is the case, then you don't need an array, you simply need another string...
Dim chars As String
chars = Left$(cellToTest, 2)
Later you can test more simply using the InStr function, like so...
Dim loc As Integer
loc = Instr(colStr, chars)
If loc > 0 Then
...
If you want to turn this into a function on your spreadsheet you can use the following in the cells as formulas...
=LEFT(A1, 2)
=SEARCH(A3, A1)
Here's a little screen shot of what I mean...

vb.net Manipulation of a string

Hello I am trying to get part of my string out and was wondering if anyone can help so here is what I am working with
Dim tempName, NewName As String
'This is an example of what tempName will Equal
'What I need is the information in between the first -
'and the second one. In this case it would be 120
'I can not do it by number because the dashes are the only thing
'that stays the same.
tempName = "3-120-12-6"
NewName = tempName 'Do not know what String Manipulation to use.
Another few examples would be 6-56.5-12-12 I need the 56.5 or 2-89-12-4 I would need the 89
Thank you for the help.
You can do this too... You can break it up into pieces by detecting the first -. Then get the second...
Dim x as String = Mid(tempName, InStr(tempName, "-") + 1)
NewName = Mid(x, 1, InStr(x , "-") - 1)
Or make something like this to get it into 1 line of code...
NewName = Mid(Mid(tempName, InStr(tempName, "-") + 1), 1, InStr(Mid(tempName, InStr(tempName, "-") + 1), "-") - 1)
Or the quickest approach to this would be to use Split like the code below... This code equates the values between - into an array. Since you want the second value, you'd want the array with the index of 1 since an array starts with 0. If you're only starting, do try to create your own way to manipulate the string, this will help your mind think of new things and not just rely on built-in functions...
Dim tempName As String = "3-120-12-6"
Dim secondname() As String = Split(tempName, "-")
NewName = secondname(1)

Application or Object defined error - VBA Excel 2013

I want code to check one column of data for a condition ie: Range Qualification. If they are required to go the the Range the value will be "REQ" if they are not the values will be "E", "S", "M", and "NR". I use [select case] to check the condition. At the start of the select case I get this error.
I am not sure if I am making the sell reference right or not. After the array is populated with names from another column, I then go through and remove the empty elements from the array and then display all elements of the array in a msgbox. Below is the code I used:
'Declares total number of personnel as integer
Dim total As Integer
total = Worksheets("MASTER").Range("C4").Value
'Declares single element array with personnel full names
ReDim names(total) As String
'Loops through the array checking to see if personnel have qualified on the Rifle Range
For i = (1 + 6) To (total + 6)
Select Case Worksheets("MASTER").Range(Cells(i, 23)).Text
Case "REQ"
names(i - 6) = Worksheets("MASTER").Range(Cells(i, 7)).Value
Case "NR"
names(i - 6) = vbNullString
Case "E"
names(i - 6) = vbNullString
Case "S"
names(i - 6) = vbNullString
Case "M"
names(i - 6) = vbNullString
End Select
Next
'Declares a new array to remove blank elements from the orignal array
ReDim msgnames(LBound(names) To UBound(names))
'Loops through new array removing empty elements
For i = LBound(names) To UBound(names)
If names(i) <> vbNullString Then
x = x + 1
msgnames(x) = names(i)
End If
Next
'Displays every element of the array
For i = LBound(msgnames) To UBound(msgnames)
msg = msg & msgnames(i) & vbNewLine
Next
'Declares COMP, NOTCOMP, REQ and NOTREQ variables
Dim COMP As String
Dim NOTCOMP As String
Dim REQ As String
Dim NOTREQ As String
'Adds a comment to the bottom of the Message Box
MsgBox msg, vbOKOnly, "Rifle Range"`
You have the wrong syntax for your range.
Change this:
Select Case Worksheets("MASTER").Range(Cells(i, 23)).Text
to this:
Select Case Worksheets("MASTER").Cells(i, 23).Value2
One other thing -- you should use .value or .value2 instead of .text unless you have a very specific reason for using .text. See Charles Williams' article for an excellent analysis of the three properties: TEXT vs VALUE vs VALUE2 - Slow TEXT and how to avoid it.