Writing string to cell - string

This should be very straightforward but for some reason I'm having issues. The code should look at a particular cell, if it meets the criteria of the IF statement, write the data to another cell.
dim i as integer
i = 1
For i = 1 To 674
If Sheets("Provider Data").Cells(i + 3, 60).Value2 = 8 Then
Sheets("Sheet1").Cells(2 + i, 1).Value2 = Sheets("Provider Data").Cells(i + 3, 3).Value2
End If
Next i
For some reason the data wont write to the cell. I've debugged with message boxes, and the If statement correctly selects the cells that match 8, but for some reason the contents of
sheets("Provider Data").cells(i+3,3).value2
aren't written to the cell. What am I missing? I should mention the data to be written to the cell from (i+3,3) are strings

Related

RIGHT function doesn't work when put within an IF statement

I want to create an IF condition using the RIGHT function. It would look up the 4 last digits within a cell and compare it to another cell, then perform actions if it's a match.
Here's a simplified version of the code I toyed with. The action to be performed in this experience is just to display the counter in a cell.
Public vCounter
Sub Counter()
vCounter = 0
Sheets.Add.Name = "Test"
'The cells the RIGHT function will operate from (A1, A2 and A3)
Sheets("Test").Range("A1") = "123"
Sheets("Test").Range("A2") = "456"
Sheets("Test").Range("A3") = "789"
'The cells the result of the RIGHT function will be compared to (B1, B2 and B3)
Sheets("Test").Range("B1") = "23"
Sheets("Test").Range("B2") = "456"
Sheets("Test").Range("B3") = "89"
'This cell (G3) shows the result of a RIGHT function, considering the
'last two digits in A1, as an experience; it works.
Sheets("Test").Range("G3") = Right(Sheets("Test").Cells(1, 1), 2)
For i = 1 To 3
'The RIGHT function considers the two last digits of, successively,
'A1, A2 and A3, and those are compared to, respectively,
'B1, B2 and B3. For some reason, it doesn't work here.
If Right(Sheets("Test").Cells(i, 1), 2) = Sheets("Test").Cells(i, 2) Then
vCounter = vCounter + 1
End If
Next i
'This cell (E3) shows the counter, to test whether or not the If
'condition with the RIGHT function works. By changing the contents
'of the cells I compare between each other, I can check whether or
'not it counts correctly.
Sheets("Test").Range("E3") = vCounter
End Sub
Here's what I get:
The sheet that I get when I run this procedure
In conclusion, in this experience, the RIGHT function somehow doesn't work since the vCounter doesn't get to 2. It stays at 0, showing it doesn't count at all. I deduce from this result that the problem resides in the IF statement containing the RIGHT function. Maybe the For Loop has to do with it, but I doubt it.
Any thoughts?
Even though you're writing string values to your sheet, Excel will automatically assume them to be numeric values, so when you read them back you will be getting values of type Variant/Double.
If you pass one of those Doubles through Right() though, it will return a Variant\String, and it's that comparison between Variant\String and Variant\Double which seems to be failing.
Some test code:
Sub Tester()
Dim ws As Worksheet, v As Variant
Set ws = ThisWorkbook.Worksheets("Test")
ws.Range("A1").Value = "123"
ws.Range("B1").Value = "23"
'Comparing values...
Debug.Print Right(ws.Range("A1").Value, 2) = ws.Range("B1").Value '>> False (Variant\String vs Variant\Double)
Debug.Print Right(ws.Range("A1").Value, 2) = CStr(ws.Range("B1")) '>> True (Variant\String vs Variant\String)
End Sub

Table from Excel to another table

Suppose there are 3 columns. In 1 column number (a1), in the second name (b1), in the third description (c1). I want to make another 1 table, so that the data would spread to it, but with 1 condition. If in the 3 column, in one cell more than 500 characters, then continue to copy the data from the rows to the next cell. (For example, there is a line a2, b2, c2 In cell c2, 600 symbols are obtained, then the remaining characters are transferred to one cell, c3 and copy the text from cells a2, b2) Is it possible to trace it? To make, some counter, that he would count the symbols in the cell.
enter image description here
table
tabletest1
Well, i think this image will be self explanatory
First table contains your original data. Right upper one contains the results, and bottom one contains the formula
The formula =IF((LEN(C2) > 5);MID(C2;6;500);" ") checks the length of the text inside a cell, if its greater than 5 (you can modify this of course), then set the value of the cell to a substring (from 6th character) of the original text.
VB Macro
After some tries, i got a VB macro which makes that
Sub copyTable()
Dim colRange As Variant
colRange = Array(1, 2, 3) 'Columns where your data is'
Dim destColRange As Variant
destColRange = Array(5, 6, 7) 'Columns where you want data be copied'
n = UBound(colRange) - LBound(colRange)
i = 2 'Initial row'
newI = i
maxLen = 10 'Maximum size allowed in one cell'
While Not (Cells(i, colRange(0)) Is Nothing) And (Cells(i, colRange(0)) <> "")
Text = Cells(i, colRange(n))
Do
For j = 0 To n - 1
Cells(newI, destColRange(j)) = Cells(i, colRange(j))
Next j
Cells(newI, destColRange(j)) = Mid(Text, 1, maxLen)
Text = Mid(Text, maxLen + 1)
newI = newI + 1
Loop Until Len(Text) <= 0
i = i + 1
Wend
End Sub
Variables explanation
colRange: Indexes of columns with origin data
destColRange: Indexes of columns where data will be written
i: Initial row
maxLen: Maximum length allowed per cell
Note that this snippet only cares about size of the last cell, if any other has more length it will copy them as they are.
when you run it you got something like
I've never made a VB code, so don't be critic, it surely can be better

Excel return all data to another worksheet based on header name

In Microsoft Excel I want to create a table to be something like in picture below.
I already try using vlookup and index but I can't make it work like I want.
Please help me
Try to use VBA:
Sub TransformTbl()
Dim i As Long, j As Long, cnt As Long
With ActiveSheet
.Range("G1:I1") = Array("Date", "Event", "Place")
cnt = 1
For j = 2 To 4 'column
For i = 2 To 5 'row
If Len(.Cells(i, j)) <> 0 Then
cnt = cnt + 1
.Cells(cnt, 7) = .Cells(1, j) 'Date
.Cells(cnt, 8) = .Cells(i, j) 'Event
.Cells(cnt, 9) = .Cells(i, 1) 'Place
End If
Next i
Next j
End With
End Sub
I wrote a solution and it works fine with me. The formula is really complex and probably hard to understand. Though I'll try my best to explain it, updating the formula may still be a difficult work. All these three formula are written in Array Formula, press ctrl+shift+enter to complete.
Formula in G6:
=IFERROR(OFFSET($A$5,0,SMALL(
IF($B$6:$D$9<>"",1,99999999)*(COLUMN($B$6:$D$9)-1),ROW(A1))),"")
The outer IFERROR keeps your sheet from any #Err. The OFFSET for calling the right date. The formula inside SMALL generate an array with the rule: If there is an event, the value will be the number of the date for offset, otherwise, it will be 99999999 which giving the OFFSET an error and be blocked by IFERROR. With the data you gave, the array will be
{ 1,99999999, 3;
1, 2,99999999;
1,99999999,99999999;
99999999,99999999, 3 }
Formula in H6:
=IFERROR(OFFSET($A$5,
SMALL(IF($B$6:$D$9<>"",ROW($B$6:$D$9)-5)*
IF(COLUMN($B$6:$D$9)=MATCH(G6,$B$5:$D$5,0)+1,1,99999999),99999999),COUNTIF($G$6:G6,G6)),
MATCH(G6,$B$5:$D$5,0)),"")
The IFERROR and OFFSET works the same as G6. The formula in OFFSET.ROW generate nearly the same array as G6. This time the value is the row of event with the date determined by column G. Other gives 999999999 or more.
Formula in I6:
=IFERROR(OFFSET($A$5,MAX((ROW($B$6:$D$9)-5)*($B$6:$D$9=H6)*
(COLUMN($B$6:$D$9)=MATCH(G6,$B$5:$D$5,0)+1)),0),"")
IFERROR and OFFSET are still the same. And this time only the event which matches the date and the name of itself has a value, other remains 0.
Finally, I apologize for the poor readability. Wish someone can help me out with this :]

Count If A or B but with no doublecounting

I have a group of cells that have strings of indicating various statements. I need it to count the cells uniquely if it has (For example) ABC, ABD, or ABQ however one cell could read " ABC ABD AMN" and that would need to be counted only once. The order is not standard.
When looking I only found the suggestion to use a "CountIf(ABC) + CountIf(ABD)+CountIf(ABQ), but that would double count multiple cells.
Then CountIfs(ABC,ABD,ABQ) counts only cells that include all of those. What method can I use to uniquely count the cells without double counting?
Set j = .Range(Cells(s, 8), Cells(e, 8))
.Cells(s - 1, 8).Value = Application.WroksheetFunction.CountIfs(j, "* ABC*", j, "*ABD*", j, "*ABQ*")
So the input cells might be
[ACD AQM AFD ABD]
[ABM ARQ ABQ ABC]
[AAA ABE ARQ]
And the output would be 2.Since two of the cells have at least one of the required phrases (ABC,ABD,ABQ). CountIfs would mistakenly give 0. CountIf + CountIf would mistakenly give 3.
You want something like this:
Set j = .Range(.Cells(s, 8), .Cells(e, 8))
With Application.WorksheetFunction
.Cells(s - 1, 8).Value = .COUNTIF(j,"*ABC*") + .COUNTIF(j,"*ABD*") - .COUNTIFS(j,"*ABC*",j,"*ABD*")
End With
Something like this will do it, may need optimization if you're working with very large column of data. The idea is to check each cell against each of the ABC, ABD, or ABQ, and exit the loop early if a matching value is found in the cell. This should prevent double-counting of cells that might match on more than one criteria.
Option Explicit
Sub foo()
Dim rng As Range
Dim i As Long
Dim word, words, val, vals
words = CountedWords
Set rng = Range("A1:A3") 'Modify as needed
vals = Application.Transpose(rng.Value)
For Each val In vals
For Each word In words
If InStr(val, word) Then
i = i + 1
Exit For
End If
Next
Next
MsgBox i
End Sub
Function CountedWords()
CountedWords = Array("ABC", "ABD", "ABQ") 'Modify as needed
End Function

Getting excel to put together split strings

I'm trying to get excel to put together a series of text strings that haven't been formatted systematically, so that they end up split into different rows on a data sheet.
I'm aware this might've been solved elsewhere so sorry for that but I'm struggling to describe the issue, and I can't post images on it but basically it's
Column 1 with a list of the entries, and
Column 2 with text strings that are spread over 2 or more rows
Is it possible to write some kind of formula or macro that would be able to check the first column and then stitch together all entries in the second column going down until it found a new entry in the first column? I've got a feeling it might be possible using some sort of loop thing with index functions, but I've no idea where to start even.
Thanks,
Mike
Mike give this a ty
Sub appendValues()
'The sub is designed to loop through code and when ever there is a null value and column a it will take the value of what is in column B and appended to the row above it and delete the row.
Dim row As Integer
row = 1
'This code starts with row one but this can be changed at will.
Do Until ThisWorkbook.Sheets("sheet1").Cells(row, 2).Value = ""
'loop statement is designed to continue to Loop until there is a null value inside of you the value in the second column.
If ThisWorkbook.Sheets("sheet1").Cells(row, 1).Value = "" Then
ThisWorkbook.Sheets("sheet1").Cells(row - 1, 2).Value = ThisWorkbook.Sheets("sheet1").Cells(row - 1, 2).Value & ThisWorkbook.Sheets("sheet1").Cells(row, 2).Value
Rows(row).Delete
Else
'else statement is needed because there is an implied looping by decreasing the total number of rows after the delete.
row = row + 1
End If
Loop
End Sub
Sub appendValues()
'The sub is designed to loop through code and when ever there is a null value and column a it will take the value of what is in column B and appended to the row above it and delete the row.
Dim row As Integer
row = 1
'This code starts with row one but this can be changed at will.
Do Until ThisWorkbook.Sheets("sheet1").Cells(row, 2).Value = ""
'loop statement is designed to continue to Loop until there is a null value inside of you the value in the second column.
If ThisWorkbook.Sheets("sheet1").Cells(row, 1).Value = "" Then
ThisWorkbook.Sheets("sheet1").Cells(row - 1, 2).Value = ThisWorkbook.Sheets("sheet1").Cells(row - 1, 2).Value & ThisWorkbook.Sheets("sheet1").Cells(row, 2).Value
Rows(row).Delete
Else
'else statement is needed because there is an implied looping by decreasing the total number of rows after the delete.
row = row + 1
End If
Loop
End Sub

Resources