Help with UDF Array

VBE313

Well-known Member
Joined
Mar 22, 2019
Messages
686
Office Version
  1. 365
Platform
  1. Windows
in the following code, I am trying to Extract just the "Y" numbers. My code gives me the answer I need, but the array UDF uses 2 columns. I only want my answer to be in column E not column F. What am I doing wrong?
2020-01-20_20-26-49.png


VBA Code:
Option Explicit
Function getY(rng As Range)
Dim i As Integer, j As Integer, n As Integer
Dim temp As Integer, A()
n = rng.Rows.Count
ReDim A(n, 1)
A = rng
    For j = 1 To n
        If A(j, 2) = "Y" Then
            temp = A(j, 1)
            A(j, 2) = ""
        Else
            A(j, 1) = ""
            A(j, 2) = ""
        End If
    Next j
getY = A
End Function
 

Excel Facts

Who is Mr Spreadsheet?
Author John Walkenbach was Mr Spreadsheet until his retirement in June 2019.
Replace
ReDim A(n, 1)
with
ReDim A(n, 1 To 1) OR ReDim A(n, 0)
Hi, thank you but I was not successful with this. What else can be wrong? here is a new code
VBA Code:
Function getY(rng As Range)
Dim i As Integer, j As Integer, n As Integer
Dim temp As Integer, A()
n = rng.Rows.Count
ReDim A(n, 0)
A = rng
    For j = 1 To n
        If A(j, 2) = "Y" Then
            i = 0
            temp = A(j, 1)
            A(j, 2) = ""
        Else
            i = i + 1
            temp = A(j - i, 1)
            A(j - i, 1) = temp + A(j, 1)
            A(j, 1) = ""
            A(j, 2) = ""
        End If
    Next j
getY = A
End Function
 
Upvote 0
I don't know. I would have to create an example to work with. If nobody helps you out by the time I get back tomorrow or you haven't figured it out by then on your own, I'll see if I can help you. Have a good one!
 
Upvote 0
I tried your first example and edited it to return an array with the correct sized dimensions. Your current function returns the same dimensions as the range passed as an argument. 2 columns. So I added an array.
VBA Code:
Function getY(rng As Range)
    Dim i As Integer, j As Integer, n As Integer
    Dim temp As Integer, A(), ret()
    n = rng.Rows.Count
    ReDim ret(1 To n, 0)
    A = rng
    For j = 1 To n
        If A(j, 2) = "Y" Then
            ret(j, 0) = A(j, 1)
        Else
            ret(j, 0) = ""
        End If
    Next j
    getY = ret
End Function

This is a long way around the block to get the results you are looking for. I suppose that you are doing this for your own learning? If not, there are easier ways to get your Y's. :)
 
Upvote 0
I tried your first example and edited it to return an array with the correct sized dimensions. Your current function returns the same dimensions as the range passed as an argument. 2 columns. So I added an array.
VBA Code:
Function getY(rng As Range)
    Dim i As Integer, j As Integer, n As Integer
    Dim temp As Integer, A(), ret()
    n = rng.Rows.Count
    ReDim ret(1 To n, 0)
    A = rng
    For j = 1 To n
        If A(j, 2) = "Y" Then
            ret(j, 0) = A(j, 1)
        Else
            ret(j, 0) = ""
        End If
    Next j
    getY = ret
End Function

This is a long way around the block to get the results you are looking for. I suppose that you are doing this for your own learning? If not, there are easier ways to get your Y's. :)
Exactly! I am doing this for my own learning! Thank you very much this worked perfectly! I loved how you used ret(). Didnt think to also create an empty array to fill the answers with. I realized that they need to be Empty instead of "".
 
Last edited:
Upvote 0
what does the 0 do here?
VBA Code:
ReDim ret(1 To n, 0)
 
Upvote 0
A range assigned to a variant or variant array always results in a two dimensional array. You know, v(Rows, Columns). The zero in the second dimension means a single column in a zero based array which is the default. Frankly, when working with ranges the semantics are a bit cleaner IMO using ReDim ret(1 To n, 1 To 1). I just use zero as a habit because most languages only allow zero based arrays.

So the following should be equivalent, but maybe a bit more clear when working with Excel ranges.
VBA Code:
Function getY(rng As Range)
    Dim i As Integer, j As Integer, n As Integer
    Dim temp As Integer, A(), ret()
    n = rng.Rows.Count
    ReDim ret(1 To n, 1 To 1)
    A = rng
    For j = 1 To n
        If A(j, 2) = "Y" Then
            ret(j, 1) = A(j, 1)
        Else
            ret(j, 1) = ""
        End If
    Next j
    getY = ret
End Function
 
Upvote 0
I'm curious, why not use a regular formula approach, e.g.:

=IF(B1:B9="Y",A1:A9,"")

Which I expect will work with Excel versions supporting dynamic arrays (which I suspect yours does). My version does not currently.

Alternatively, you could also probably limit it to one column using INDEX, e.g:

=INDEX(getY(A1:B9),0,1)
 
Upvote 0
Upvote 0

Forum statistics

Threads
1,214,918
Messages
6,122,255
Members
449,075
Latest member
staticfluids

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top