3

I'm running a code to create a daily report, first I was working with cells and offsets to compare the date but that was slow, now I'm using arrays to improve the code, but I'm encountering a problem when trying to use some application functions, first I tried VLookup and all I got was Run-time error '13': Type mismatch. Now I'm working with Match and Index methods and I get the same error, I can't seem to find what my error is.

I'm passing a Variant Array, that I get this way:

Public wsrgcmes As Variant
Public wshtte As Variant

With Sheets("Resumen general de casos")
    wsrgcmes = .Range(.Cells(1, 2), .Cells(lRow, lCol)).Value
End With

And the error comes here, when I try to execute the Application.Index method.

Sub gen_informe()    
     temp = Application.Index(wsrgcmes, 0, 1)        
End Sub

I ran only this line Application.Index(wsrgcmes, 0, 1) in the debug window and I got the same error. The Variant Array wsrgcmes contains a table with numeric and string values. Any help I cant get, I appreciate it. Thanks!

Values of wbrgc:

enter image description here

Vityata
  • 42,633
  • 8
  • 55
  • 100
Datalyzer
  • 33
  • 5
  • Where is this array declared? If you don't specify a data type or structure then Excel's going to have to "guess". – ashleedawg Apr 19 '18 at 12:51
  • Put structure of `wsrgcmes` array. – Harun24hr Apr 19 '18 at 12:52
  • 1
    Add a watch on wsrgcmes to make sure that the array wsrgcmes is populated correctly. Check the value of lRow and lCol also. – Subodh Tiwari sktneer Apr 19 '18 at 12:59
  • 1
    Is wsrgcmes a public array? – QHarr Apr 19 '18 at 13:02
  • @QHarr Yes, sorry. Forgot to mention that, `wsrgcmes` is a Public Array, because I use it in several Subs. – Datalyzer Apr 19 '18 at 13:08
  • 2
    It is 1 based array since you are building from range. My immediate guess would be to test with `temp = Application.Index(wsrgcmes, 1, 1)`. – shrivallabha.redij Apr 19 '18 at 13:10
  • What are you expecting `wsrgcmes` to contain? Also can you show how it is declared? – ashleedawg Apr 19 '18 at 13:11
  • @shrivallabha.redij I want that function to return a column from the array, so I can match a value, since I understand Match only works with 1D arrays. – Datalyzer Apr 19 '18 at 13:18
  • @ashleedawg It's declared like this `Public wsrgcmes As Variant`, and `wsrgcmes` contains text and numbers (doubles mosntly). – Datalyzer Apr 19 '18 at 13:20
  • What is the length of the column you are trying to slice btw? I am guessing you are aware of the limitations with Index for slicing? – QHarr Apr 19 '18 at 13:22
  • @QHarr I'm not aware of the limit, maybe that could be the cause of my problem. The current length of the column is 14630 this far – Datalyzer Apr 19 '18 at 13:27
  • Just curious, does the attached file code work at your end? https://www.dropbox.com/s/x6lgy5zieu0vvhn/SO_49921531.xlsm?dl=0 – shrivallabha.redij Apr 19 '18 at 17:44
  • @shrivallabha.redij Hey! It works. Check https://imgur.com/a/oFE7uv6 – Datalyzer Apr 19 '18 at 18:19
  • What datatype is temp? A variant? – jeffreyweir Apr 19 '18 at 23:38
  • Also, can you tell us more about your intent with this code? You say you want to "compare the date". I'd suggest you post a screenshot of your data in Excel that includes the dates in the data, and explain what you want to compare them against, and what you want to happen next. Might be a much simpler approach that doesn't actually require this array manipulation in the first place. – jeffreyweir Apr 19 '18 at 23:45
  • Hmm, it makes me think that there's something else in your complete code which is causing it to fail. Code logic above and the current conditions don't seem to cause problems. I had totally forgotten about usage of 0 in `Application.Index`. Take a look at what @jeffreyweir has suggested. – shrivallabha.redij Apr 20 '18 at 08:45

4 Answers4

2

When you get the values of a range to a Variant, it is always a 1-based 2D array:

"locals" toolwindow in the VBE debugger showing array indices

Thus row index 0 is out of the array bounds, and Application.Index raises a type mismatch error in that case.

Public Sub TestMe()        
    Dim a As Variant
    a = Range("A1:D5").Value2
    Debug.Print Application.Index(a, 1, 2)    
End Sub

From the comment of @Mathieu Guindon:

Application is, in COM terms, an extensible interface - it's extended with WorksheetFunction members at run-time, so Application.Index does work, even though it's a late-bound member call (no intellisense). It behaves slightly different than its early-bound equivalent, in that instead of raising a run-time error given an error result, it returns the error result (e.g. #VALUE!).

Both syntaxes are perfectly valid, and each demand different error-handling mechanics (early-bound: On Error..., late-bound: IfError(...))

Vityata
  • 42,633
  • 8
  • 55
  • 100
  • Thanks for your answer. As suggested before, I tried `Debug.Print Application.Index(wsrgcmes, 1, 1)` and I keep getting the same mistmatch error. Is there another workaround to this, can't find what I'm doing wrong. – Datalyzer Apr 19 '18 at 13:40
  • @SebasXHP - select the word `wsrgcmes` in your VBEdtior, press `Shift+F9` and put a screenshot of what you see on the question. – Vityata Apr 19 '18 at 13:44
  • This I what I get, no values. And I know there's data because I used it for another three loops and I got the info I wanted from it. I just have problems with VLookup and Index. https://imgur.com/a/Hx1EIiH – Datalyzer Apr 19 '18 at 14:05
  • @SebasXHP - press "Agregar" And then press the small `+`, if you see it. – Vityata Apr 19 '18 at 14:07
  • And now if you do the `Application.Index(wsrgcmes,14630,1)` you get an error? – Vityata Apr 19 '18 at 14:19
  • I just ran `Debug.Print Application.Index(wsrgcmes, 14630, 1)` and I got the mismatch error. – Datalyzer Apr 19 '18 at 14:26
1

Application.Index has a limit for number of columns and rows. If you exceed this you will hit a type mismatch error. So this might be the problem.

See the following for ways to work around this:

how-do-i-slice-an-array-in-excel-vba

I am not sure what the current limit is. It was more than 65,536 rows or 65,536 columns. The solution in the links is essentially to use arrays to slice rather than Application.Index.

If you pay attention to @Vityata's answer and Index appropriately you can probably determine the tipping point at which you tip over into type mismatch. In some circumstances you can also work around this by processing columns/rows in chunks to stay under the threshold. I give an example of working in chunks to get around this here: Slice array to use index on larger than 65000.

You could completely avoid Index and use TimWilliams helper function .

Using @TimWilliams helper function you would have

Sub test 'your other sub

temp = GetColumn(wsrgcmes,1)

End Sub


Function GetColumn(arr, colNumber)
    Dim arrRet, i As Long
    ReDim arrRet(1 To UBound(arr, 1), 1 To 1)
    For i = 1 To UBound(arr, 1)
        arrRet(i, 1) = arr(i, colNumber)
    Next i
    GetColumn = arrRet
End Function
QHarr
  • 83,427
  • 12
  • 54
  • 101
  • Hey! I tried the function you suggested and It actually works. It does what I wanted it to do. Thank you very much. Maybe it's too much to ask, but do your know if there's a way to do that but quicker? Now it's taking kinda long to finish, I know there are a lot of iterations to get done, but if I can get it working faster it would be great. Thanks a lot. – Datalyzer Apr 19 '18 at 19:19
  • I hope that doesn't feel too much like a re-direct but they are awesome over there at reviewing code and code optimization is their bag. One really needs to see the code in its entirety to start understanding where to make optimizations beyond switching off the usual suspects like screenupdating, calculation mode etc. – QHarr Apr 19 '18 at 19:27
  • I don't believe the issues is caused by INDEX's limitations. As per my answer, INDEX will handle over 1048576 rows, but is limited to 65536 columns. The original issue (i.e. error when printing to immediate window) is entirely down to OP trying to print an array, I believe. – jeffreyweir Apr 19 '18 at 23:37
  • @jeffreyweir Nice to hear from you. Seems like I jumped the gun. Good to know. Where are these limitations listed as I can never remember them? On MSDN? I'll have a look at your answer as this will be good learning for me. Prior comment deleted. – QHarr Apr 20 '18 at 04:40
  • 1
    @QHarr I didn't look on MSDN...I just whipped up some code and checked when it threw an error :-) – jeffreyweir Apr 20 '18 at 04:42
  • Not a here's one I made earlier? Lol :-) – QHarr Apr 20 '18 at 04:42
  • @jeffreyweir Thanks for your help! I did tried to print the array, because I wanted to check if worked that way, but I got the error before I tried that. Now I know it won't show the array that way. What my code is trying to do is compare dates to get for example the number of service tickets registered in a certain day during a month, which ones were closed the same day, which ones were closed the current day and were registered in another month, which ones were closed out of the SLA, etc. Sample of my code is here https://drive.google.com/file/d/1q_KJEmOTtINt7xZaEY7VXliDH8G4CL5l/view – Datalyzer Apr 21 '18 at 14:39
  • Yes, it did fixed it and it works, thank you very much. But to be honest, I would like to know why that Index doesn't work. I did another implementation before reading the info from the cells, doing cell transactions all the time and it was slow, so I posted my code on code review and I did what they told me, turn off events and automatic calcs, etc. Also they told me to load all the info to arrays because that way would be faster, and that's what I did, and with the fix you suggested it is as slow as my first implementation, so that bugs me a bit. – Datalyzer Apr 21 '18 at 15:33
  • grrr... that is frustrating! I am not sure what else to suggest I'm afraid as they are way more experienced than me. Sorry. – QHarr Apr 21 '18 at 15:38
  • Don't worry. Thank your very much and thanks to everyone. I was working on this code at work where I got Office 2016 (32bits) installed. Now I just ran the same code at home and for my surprise it ran without errors at the Index method, I checked the temp array and it's perfect. Maybe the problem was related to the Excel version or some update, because I got Office 2016 (64bits) at home, and it is updated. Now I just have to optimize my code. Thanks again to everyone that helped, the answer by @QHarr was the one that solved my problem, a nice workaround to substract my column. – Datalyzer Apr 21 '18 at 21:05
1

When you feed the INDEX funciton a 0, you're telling it "I want the entire row or column".

If you assign Application.Index(wsrgcmes, 0, 1) to a variant, it works fine...you've got a variant with an array in it.

If you try to print Application.Index(wsrgcmes, 0, 1) to the immediate window, you get an error because you're trying to print an array. You need to wrap it in a JOIN function.

I don't know why you are getting an error on Application.Index(wsrgcmes, 14630, 1) but my guess is that at the time you did it, wsrgcmes wasn't populated or wasn't that dimension. I'd need to see a screenshot of both the exact part of the code you were using when the error occurred as well as a screenshot of the array in the Watch Window.

I don't believe your issue is caused by the limitations of INDEX, because you are nowhere near them.

The below code shows the limitations of INDEX when called from VBA:

 Sub IndexLimitations()

Dim v       As Variant
Dim i       As Long
Dim j       As Long
Dim k       As Long
Dim vArray  As Variant
Dim vItem   As Variant

vArray = Array(65536, 65537, 1048576, 1048577)

For Each vItem In vArray
    i = vItem
    ReDim v(1 To i, 1 To 2)
    For j = 1 To i
        For k = 1 To 2
            v(j, k) = j * k
        Next k
    Next j
    Debug.Print "Rows dimension test: " & i
    Debug.Print Application.Index(v, i, 1)
    Debug.Print ""

    ReDim v(1 To 2, 1 To i)
    For j = 1 To i
        For k = 1 To 2
            v(k, j) = j * k
        Next k
    Next j

    Debug.Print "Columns dimension test: " & i
    Debug.Print Application.Index(v, 1, i)
    Debug.Print ""

Next vItem

End Sub

Here's what it returns:

Rows dimension test: 65536
 65536 

Columns dimension test: 65536
 65536 

Rows dimension test: 65537
 65537 

Columns dimension test: 65537
Error 2023

Rows dimension test: 1048576
 1048576 

Columns dimension test: 1048576
Error 2023

Rows dimension test: 1048577
 1048577 

Columns dimension test: 1048577
Error 2023

The learning here is that you are limited to 65536 columns if using the INDEX function to return a column, but you don't seem to be limited to the number of rows in the grid. I suspect this is related to the TRANSPOSE bug I mention in passing at http://dailydoseofexcel.com/archives/2013/10/23/dictionaries-can-be-rude/

jeffreyweir
  • 4,668
  • 1
  • 16
  • 27
  • Hey! Thanks for your help. So I'm not having limitations yet by using the Index method. Also `wsrgcmes` is being populated from the very beggining since first I run a sub for loading the arrays and then I run the sub to create the report. This is the screenshot you asked for, if you need any other info I will provide ir. Thank you very much. https://imgur.com/a/fhNAyCh – Datalyzer Apr 20 '18 at 15:54
  • Ok. So can you give us the line showing where wsrgcmes is declared? e.g "DIM wsrgcmes as...". And just to confirm, what error do you get on that line if you push F8 when it is highlighted? – jeffreyweir Apr 20 '18 at 20:14
  • It's declared at the start, out of the subs `Public wsrgcmes As Variant` and when I run that line, there's no error being shown. The info is being loaded into that Variant Array because I have used the information for other things, but when I used the Index function, is where I get the problems. – Datalyzer Apr 20 '18 at 21:05
  • And to confirm, it is throwing an error at that particular line? I.e. if you push F8 at the stage you're at in that screenshot, it gives you an error there? – jeffreyweir Apr 20 '18 at 21:08
  • No, it just sends me to the beginning of the sub. It's really weird. I will try deleting the lines of code I got before the line where I get the error and see if runs without problems. – Datalyzer Apr 20 '18 at 21:46
  • Comment out any use of "On Error Resume Next"...they may be masking your real issue. – jeffreyweir Apr 20 '18 at 21:48
  • I just did and I get the same error. I will post my file and sample of the info my code is using. Maybe you can check it please, if that's not a problem. Thanks ! https://drive.google.com/open?id=1q_KJEmOTtINt7xZaEY7VXliDH8G4CL5l – Datalyzer Apr 20 '18 at 22:16
0

I also have this problem, see here . I think that application.Indexcannot be applied to arrays containing different types of variables. I had a 100 X 2 array containing double type in the first column and string in the second one. I could not use application.Index to paste contents from my array to the excel sheet, even if I selected contents of the same type (from just column 1 or 2). Then I substituted the string type values vith numerical double values, and this time application.Index worked correctly. However, we still don't know if application.Index works only with numerical types.

Tms91
  • 3,456
  • 6
  • 40
  • 74