VBA convert range to array and format date - excel

I am struggling with a conversion to array in VBA :
Dim list As Range
Set list = Range(series, series.End(xlDown))
list.Select
Dim table() As Variant
Set table = list.value
My understanding is that value returns an array right ? I don't get why VBA tells me that I "can't assign to array".
My list range looks like that in Excel at the Select, and i aim at having that as an array so that I can format my dates using something like Format(table.Rows(i).Columns(1).value, "yyyy-mm-dd"), looping on my table.
02-Sep-09 1.00
18-Sep-09 1.00
16-Oct-09 1.00
20-Nov-09 1.00
18-Dec-09 1.00
19-Mar-10 1.00
18-Jun-10 1.00
By the way, is it possible to modify the table in place ?
Thanks !

There are a number of problem here.
Problem 1
Set table = list.value
table is not an object so you cannot set it. Try:
table = list.value
Problem 2
series is a VBA keyword associated with charts. Please pick a name, such as MyWSTable, which means nothing to VBA.
Problem 3
A worksheet name is not itself a range. Try:
Dim Table() As Variant
Table = Names("MyWSTable").RefersToRange.Value
Note: you do not need variable list nor do you need to select the range.
Answer to formatting question
The following code will reformat your dates:
For inxrow = 1 To UBound(Table, 1)
For inxcol = 1 To UBound(Table, 2)
Table(inxrow, 1) = "ddd d mmm yyyyy"
Table(inxrow, 2) = ""
Next
Next
Names("MyWSTable").RefersToRange.NumberFormat = Table

You can remove your select: list.Select
To be sure you won't get errors when assigning a range to an array, you'd better declare your array as a variant:
Dim table As Variant
table = Range(series, series.End(xlDown)).Value

That error message is popping because you are using SET to fill the array. Drop the SET and it should load.
You can fil directly the array as follows:
Dim table() As Variant
table=Range(series, series.End(xlDown))
Omiting the Select step makes your code safer and faster.
Unfortunately, you can not load the values directly as dates. You will have to loop throu every item of the array and turn them into date.

You are going about this incorrectly. You should use the NumberFormat property of the range to specify the display format. Something like this:
Range("A:A").NumberFormat = "yyyy-mm-dd"

Related

Combine columns of data in excel into one column without changing sequence

I know this question has been asked before but I couldn't follow the instructions from the previous post to make it work. I am trying to combine a few columns of data that look like Table on the left is what I have trying to get to table on the right the block of data on the left which I want to combine into one, unchanged row (the sequence is very important as it follows a time series). I am compiling data for all 50 states in a separate table where I want to paste this column into. The data runs from columns (A:AY). Help would be greatly appreciated cause I really don't know what I am doing(complete novice here, I have no experience with VBA). A proper breakdown of the process would be greatly appreciated.
I tried using the CONCATENATE funcion but keep running into an error, I found a few torubleshooting methods on google but they seem to interrupt the sequence of data. I tried using the tutorial from This but couldn't get it to work.
In case you don't have tocol, you can just as well use INDEX, like so.
Table named "data":
col1
col2
col3
a
g
m
b
h
n
c
i
o
d
j
p
e
k
q
f
l
r
Then this formula will put the data into a single column. Just put it anywhere in the first row, change "data" to your input range and expand down.
=INDEX(data,MOD(ROW()-1,ROWS(data))+1,CEILING.MATH(ROW()/ROWS(data)))
Or, if your data is very large and you don't want to expand manually, you can try this VBA approach.The only thing you need to change is the "data" and "targetCell" variables at the top.
"data" is your original table so in your example, it would be Range("B2:F12"). "targetCell" is where the column will start. In your Example it's Range("BC2")
Sub singleColumn()
Dim data As Range, targetCell As Range, targetRange As Range
Set data = Range("data")
Set targetCell = Range("G20")
Dim resultArr() As Variant, arr As Variant
ReDim resultArr(1 To data.Rows.Count * data.Columns.Count, 1 To 1)
arr = data
For i = 1 To UBound(resultArr)
resultArr(i, 1) = arr(((i - 1) Mod UBound(arr)) + 1, WorksheetFunction.Ceiling_Math(i / UBound(arr)))
Next i
Set targetRange = Range(targetCell, Cells(targetCell.Row + UBound(resultArr) - 1, targetCell.Column))
targetRange = resultArr
End Sub

Why is midnight added to my array instead of the date?

I declare a date array as such:
Dim date_array() as Date
It's goal is to store dates found in a range.
Dim date_range As String
I declare it as a string because I have an input form where a user specifies the range of dates (e.g. A1:A5).
Then I calculate how many cells are in the range and specify the size of the date_array.
ReDim date_array(Range(date_range).Cells.count)
So far so good. I then loop through each element of date_array and add the date from the range.
Dim i As Long
i = 0
For Each r In ThisWorkbook.Worksheets("Name").Range(date_range)
date_array(i) = r.Value
i + i + 1
Next r
However, when I do a MsgBox(date_array(i)) during this loop, I get a value of 12:00:00 AM instead of the date I want (e.g. 2/2/2019) which tells me something is getting lost in translation.
I get the correct result if I do MsgBox(r.Value)... so it seems like something about the way I'm assigning the date to the array is wrong.
Has anyone run into an issue like this before? How can I fix it?
The larger goal is to map data between two files using date + a naming convention as a validation, so I need the array to store the correct date in a date format so it can be compared to a different cell value later.
Thank you,

Look up and return values from 2 columns all matches

I have List A and B in excel and would like to compare ALL the items in List A with ALL the records in List B and if they match or partial match return the value of B in 3rd column. Hopefully demonstrated in the attached.
example
The easiest way to achieve it is to use VBA. Please find below example function which you can use in the same way as Excel functions:
Public Function findArea(item As String, areaRng As Range) As String
Dim i As Long
Dim ARR_area() As Variant
ARR_area = areaRng.Value2
For i = LBound(ARR_area) To UBound(ARR_area)
If (item Like "*" & ARR_area(i, 1) & "*") Then
findArea = ARR_area(i, 1)
GoTo endFunc
End If
Next i
endFunc:
End Function
Where:
item - Item which you want to check vs. areas
area - range of areas you want to check.
See usage example:
To achieve this result without you would need to format table to pivot view, where in rows you would have item and in rows area - as the value you can check matching for each combination. Nevertheless in this particular example I would recommend to use VBA.
Hope it helped.

How do I search for numbers within a range that are written in a specific format?

I am trying to write an Excel formula that measures the number of times a number between 1000 and 9999 is written in text using the format 0,000. (This is being used to read old content from our website and measure how many pages do not align with a new style guide.) Here is what I have so far:
=count(search(text(1000,"0,000"),G17))
This formula works if the text in the content is 1,000, but, obviously, not if the text is 1,001.
I don't know how to enter the range in. I assume it should go where the 1000 is, but nothing I try works.
Does anyone know how to do this?
If your text-based number values in column G are between 0 and 999,999 then this should return a count of all text-based numbers that would have a numerical value between 1000 and 9999 if they were actually numbers.
=SUMPRODUCT(COUNTIF(G:G, {"1,*","2,*","3,*","4,*","5,*","6,*","7,*","8,*","9,*"}))
Another approach is that anything between 1,000 and 9,999 is going to have a length of 5.
=SUMPRODUCT(--(LEN(G:G)=5))
If you add the following code to a new "Module" in the VBA Editor you will have access to it as a worksheet function.
I've not tested it all that much but it worked for my example.
Public Function RESearch(SourceText) As Integer
Dim REO As Object: Set REO = CreateObject("VBScript.RegExp")
REO.Pattern = "(\d{1},\d{3})"
REO.Global = True
REO.IgnoreCase = False
REO.MultiLine = True
Dim Matches As Variant
Set Matches = REO.Execute(SourceText)
RESearch = Matches.Count
Set REO = Nothing
End Function
This will add a function "RESearch" to the workbook, and should return the count of all numbers that match the pattern.
Try this:
=COUNTIF(G:G,"?,???")

Read out Excel cell with mixed text color using Matlab

I have troubles to read out the font information of an Excel cell containing text of mixed color with Matlab using ActiveX.
Take as an example an excel file with the string "GreenBlueRedBlack" in cell A1 with respective parts of the string in stated color.
MyExcel = actxserver('Excel.Application');
Workbook = MyExcel.Workbooks.Open('D:\data\Test.xlsx');
MySheet = MyExcel.ActiveWorkBook.Sheets.Item(1);
Text=get(MySheet.Range('A1').Characters,'Text');
Color=MySheet.Range('A1').Characters.Font.Color; % provides NaN
for m=1:size(Text,2) % read out letters seperately
Color(m)=MySheet.Range('A1').Characters(m,1).Font.Color;
end
The code of course provides NaN when indexing to the whole cell.
I am unable to find a way to correctly subindex and loop through each letter in the cell.
If I understood correctly Characters(x,y) should be fed with startpoint and length of the wanted subpart of the cell. But Characters(1,1) only returns NaN and Characters(2,1) as well as Characters(1,2) exceeds the matrix dimensions.
How does subindexing to a substring of a cell work?
Thank you.
I found a workaround, maybe somebody can benefit from it.
Add following Code into the Module1 of the Excel file.
Public Function getCellInfo(Row As Variant, Col As Variant, Sheet As Variant)
ActiveWorkbook.Sheets(Sheet).Activate
Text = Cells(Col)(Row).Text
TextLength = Len(Cells(Col)(Row))
Dim Color() As Variant
ReDim Color(TextLength)
For m = 0 To TextLength - 1
Color(m) = Cells(Col)(Row).Characters(m + 1, 1).Font.Color
Next
getCellInfo = Color
End Function
Then call the macro from Matlab using:
ColorVector=MyExcel.Run('getCellInfo',Sheet,Row,Col);
It's not very pretty though. If somebody knows a more elegant way without calling an excel macro that would be awesome.
Maybe too late, but this is the solution :
color = MySheet.Range('A1').get('Characters', start, length).Font.Color;

Resources