Following this code, I got a strange behavior. assigning to one range object cause change also in another object
Sub test()
Dim pRange1 As Word.Range
Dim pRange2 As Word.Range
' ActiveDocument.Range => String "12"
Set pRange1 = ActiveDocument.Range.Characters(1) 'pRange1 =1
'
Set pRange2 = ActiveDocument.Range.Characters(2) 'pRange1 =2
pRange1.Text = "3" ' pRange1=3 and pRange2=33 ????!!!
End Sub
Why after assignment of
pRange1.Text = "3"
pRange1 object also changed?
I think this is what's happening (I am open to corrections):
The first thing to note is that Range.Characters(1) is the same as Range(0, 1) which means the range starting at character with index 0 up to but not including character with index 1
It appears to me that setting Range.Text = "ab" happens in two stages. First the range is deleted (Range.Delete) and then the text "ab" is assigned to the range.
The following code should explain the behaviour:
Sub Test()
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
With ActiveDocument
.Range = "abc"
Set r1 = .Range(0, 1) '* similar to .Characters(1)
Set r2 = .Range(1, 2) '* similar to .Characters(2)
Set r3 = .Range(2, 3) '* similar to .Characters(3)
'* At this point r1, r2 and r3 are distinct ranges
Debug.Print "Before:"
Debug.Print "-------"
Debug.Print "r1: " & r1 & vbTab & "start index: " & r1.Start & vbTab & "end index: " & r1.End
Debug.Print "r2: " & r2 & vbTab & "start index: " & r2.Start & vbTab & "end index: " & r2.End
Debug.Print "r3: " & r3 & vbTab & "start index: " & r3.Start & vbTab & "end index: " & r3.End
r1.Delete
'* At this point r1 is a subset of r2. Therefore, changing
'* r1 will change r2. r3 is a distinct range
Debug.Print
Debug.Print "After Deletion:"
Debug.Print "---------------"
Debug.Print "r1: " & r1 & vbTab & "start index: " & r1.Start & vbTab & "end index: " & r1.End
Debug.Print "r2: " & r2 & vbTab & "start index: " & r2.Start & vbTab & "end index: " & r2.End
Debug.Print "r3: " & r3 & vbTab & "start index: " & r3.Start & vbTab & "end index: " & r3.End
r1.Text = "z"
'* At this point r1 is still a subset of r2. r3 is a distinct range
Debug.Print
Debug.Print "After Adding Text:"
Debug.Print "------------------"
Debug.Print "r1: " & r1 & vbTab & "start index: " & r1.Start & vbTab & "end index: " & r1.End
Debug.Print "r2: " & r2 & vbTab & "start index: " & r2.Start & vbTab & "end index: " & r2.End
Debug.Print "r3: " & r3 & vbTab & "start index: " & r3.Start & vbTab & "end index: " & r3.End
End With
End Sub
The output is:
Before:
-------
r1: a start index: 0 end index: 1
r2: b start index: 1 end index: 2
r3: c start index: 2 end index: 3
After Deletion:
---------------
r1: start index: 0 end index: 0
r2: b start index: 0 end index: 1
r3: c start index: 1 end index: 2
After Adding Text:
------------------
r1: z start index: 0 end index: 1
r2: zb start index: 0 end index: 2
r3: c start index: 2 end index: 3
Edit: (following comment below)
Here's a not-so-pretty workaround. The main idea is to insert the new text and then delete the old text. This way the next range r2 doesn't collapse into the current range r1 (i.e. distinct ranges remain separate).
Sub Test2()
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
With ActiveDocument
.Range = "abc"
Set r1 = .Characters(1)
Set r2 = .Characters(2)
Set r3 = .Characters(3)
Debug.Print "Before:"
Debug.Print "-------"
Debug.Print "r1: " & r1 & vbTab & "start index: " & r1.Start & vbTab & "end index: " & r1.End
Debug.Print "r2: " & r2 & vbTab & "start index: " & r2.Start & vbTab & "end index: " & r2.End
Debug.Print "r3: " & r3 & vbTab & "start index: " & r3.Start & vbTab & "end index: " & r3.End
ReplaceRangeText r1, "z"
Debug.Print
Debug.Print "After:"
Debug.Print "------"
Debug.Print "r1: " & r1 & vbTab & "start index: " & r1.Start & vbTab & "end index: " & r1.End
Debug.Print "r2: " & r2 & vbTab & "start index: " & r2.Start & vbTab & "end index: " & r2.End
Debug.Print "r3: " & r3 & vbTab & "start index: " & r3.Start & vbTab & "end index: " & r3.End
End With
End Sub
Function ReplaceRangeText(rng As Range, sNewText As String) As Range
Dim sOldText As String
With rng
sOldText = .Text
.InsertBefore sNewText
.Document.Range(.Start + Len(sNewText), .End).Delete
End With
Set ReplaceRangeText = rng
End Function
The output is:
Before:
-------
r1: a start index: 0 end index: 1
r2: b start index: 1 end index: 2
r3: c start index: 2 end index: 3
After:
------
r1: z start index: 0 end index: 1
r2: b start index: 1 end index: 2
r3: c start index: 2 end index: 3
Related
I am trying to find if some mandatory values are filled in particular cells or not. But When I try to find value of cell AI and BM, excel throws me Error 1004 but it works fine for cells X and Y. Any idea how to correct this?
Row 1 has my headers.
Private Sub CommandButton1_Click()
Dim value As Range, sheetRange As Range
Dim j As Integer
Dim lRow As Integer
Set sheetRange = Sheet4.Range("A2:BM65536")
On Error Resume Next
Set value = Intersect(sheetRange.EntireRow.SpecialCells(xlConstants), sheetRange)
On Error GoTo 0
If value Is Nothing Then
MsgBox "Good to go"
Exit Sub
Else
lRow = Cells(Rows.Count, 1).End(xlUp).Row
For j = 2 To lRow
If Len(Sheet4.Range("X" & j).value) = 0 Then
MsgBox "Enter value for: Data sheet" & vbNewLine & "Column name: " & Range("X1").value & vbNewLine & "Cell X" & j, vbExclamation
Exit Sub
End If
If Len(Sheet4.Range("Y" & j).value) = 0 Then
MsgBox "Enter value for: Data sheet" & vbNewLine & "Column name: " & Range("Y1").value & vbNewLine & "Cell Y" & j, vbExclamation
Exit Sub
End If
If Len(Sheet4.Range("AB" & j).value) = 0 Then
MsgBox "Enter value for: Data sheet" & vbNewLine & "Column name: " & Range("AB1").value & vbNewLine & "Cell AB" & j, vbExclamation
Exit Sub
End If
If Len(Sheet4.Range("AI" & j).value) = 0 Then
MsgBox "Enter value for: Data sheet" & vbNewLine & "Column name: " & Range("AI").value & vbNewLine & "Cell AI" & j, vbExclamation
Exit Sub
End If
If Len(Sheet4.Range("BM" & j).value) = 0 Then
MsgBox "Enter value for: Data sheet" & vbNewLine & "Column name: " & Range("BM").value & vbNewLine & "Cell BM" & j, vbExclamation
Exit Sub
End If
Next
End If
End Sub
The issue is that in your MsgBox line of AI and BM the & Range("AI").value & returns an array of values, because AI is the whole column.
You probably meant to use & Range("AI1").value & to return the header name only.
Same for & Range("BM").value &.
This code is designed to detect the columns of start and finish of a shape which is used and displayed onto the caption of the shape itself. The following code is the problematic code:
Sub Take_Baseline()
Dim forcast_weeksStart() As String
Dim forcast_weeksEnd() As String
Dim forcastDate As String
Dim shp As Shape
Dim split_text() As String
'cycle through all the shapes in the worsheet and enter the forcast date for all the projects into their respective boxes
For Each shp In ActiveSheet.Shapes
'initialize forcast date by parsing
forcast_weeksStart = Split(shp.TopLeftCell.Column.Text, " ")
forcast_weeksEnd = Split(shp.BottomRightCell.Column.Text, " ")
forcastDate = forcast_weeksStart(1) & "-" & forcast_weeksEnd(1)
temp = shp.OLEFormat.Object.Object.Caption
If InStr(temp, "/-/") > 0 & InStr(temp, "In Prog") Then
split_text = Split(shp.OLEFormat.Object.Caption, " ")
For i = 0 To (i = 3)
shp.TextFrame.Characters.Caption = split_text(i) & vbNewLine
Next i
ActiveSheet.Shapes(Sheet4.Range("B1")).TextFrame.Characters.Caption = ActiveSheet.Shapes(Sheet4.Range("B1")).TextFrame.Characters.Caption & vbNewLine & ActiveSheet.Cells(4, AShape.TopLeftCell.Column).Text & " - " & ActiveSheet.Cells(4, AShape.BottomRightCell.Column).Text & vbNewLine & "dates: " & forcast_weeksStart(1) & " - " & forcast_weeksEnd(1) & "/" & forcast_weeksStart(1) & " - " & forcast_weeksEnd(1) & "/" & "/" & "actualDate"
' ElseIf InStr(temp, "/-/") > 0 & InStr(temp, "In Prog") = 0 Then
'split_text = Split(shp.OLEFormat.Object.Object.Caption, " ")
' For i = 0 To (i = 2)
' shp.OLEFormat.Object.Caption = split_text(i) & vbNewLine
' Next i
'ActiveSheet.Shapes(Sheet4.Range("B1")).TextFrame.Characters.Caption = ActiveSheet.Shapes(Sheet4.Range("B1")).TextFrame.Characters.Caption & vbNewLine & "In Prog" & vbNewLine & ActiveSheet.Cells(4, AShape.TopLeftCell.Column).Text & " - " & ActiveSheet.Cells(4, AShape.BottomRightCell.Column).Text & vbNewLine & "dates: " & forcast_weeksStart(1) & " - " & forcast_weeksEnd(1) & "/" & forcast_weeksStart(1) & " - " & forcast_weeksEnd(1) & "/" & "actualDate"
End If
Next shp
'For testing purposes
Sheet4.Range("A20").Value = forcast_weeksStart(1)
Sheet4.Range("A21").Value = forcast_weeksEnd(1) End Sub
The error is an
"invalid qualifier"
message which occurs on line
forcast_weeksStart = Split(shp.TopLeftCell.Column.Text, " ")
Right on the "column" word. I don't get why this is happening since the actual drop down menu has the column operation which i can select. I have tried everything from changing it to the OLEformat.Object.Caption etc etc. But nothing has worked. I am still relatively new to vba so any help will be appreciated. Thanks
I have the below Excel 2010 VBA that is in two parts. The first portion checks if a CheckBox on a sheet is checked, if it then it adds the value of a specified cell to the sample_descriptor.txt in the portion below that. Currently I am getting a
subscript out of range error
and am not sure if this is the best way to accomplish this task. Thank you :). The value for comment1 is F9, comment2 is F10, comment3 is F11, and comment4 is F12
VBA
' ADD COMMENT IF ANY '
If CheckBox17.Value = True Then
Worksheets("Sheet1").Range("F9") = ActiveSheet.Range("F9").Value
Else
Worksheets("Sheet1").Range("F9") = "No Issues"
End If
If CheckBox17.Value = True Then
Worksheets("Sheet1").Range("F10") = ActiveSheet.Range("10").Value
Else
Worksheets("Sheet1").Range("F10") = "No Issues"
End If
If CheckBox17.Value = True Then
Worksheets("Sheet1").Range("F11") = ActiveSheet.Range("F11").Value
Else
Worksheets("Sheet1").Range("F11") = "No Issues"
End If
If CheckBox17.Value = True Then
Worksheets("Sheet1").Range("F12") = ActiveSheet.Range("F12").Value
Else
Worksheets("Sheet1").Range("F12") = "No Issues"
End If
Unload Me
'WRITE TO SAMPLE DESCRIPTOR.txt '
Open MyDirectory & "sample_descriptor.txt" For Output As #1
Print #1, "Experiment Sample" & vbTab & "Control Sample" & vbTab & "Display Name" & vbTab & "Gender" & vbTab & "Control Gender" & vbTab & "Spikein" & vbTab & "Location" & vbTab & "Barcode" & vbTab & "Medical Record" & vbTab & "Date of Birth" & vbTab & "Order Date"
Print #1, "2571683" & MyBarCode & "_532Block1.txt" & vbTab & "2571683" & MyBarCode & "_635Block1.txt" & vbTab & ActiveSheet.Range("B8").Value & " " & ActiveSheet.Range("B9").Value & vbTab & ActiveSheet.Range("B10").Value & vbTab & ActiveSheet.Range("B5").Value & vbTab & Split(ActiveSheet.Range("B11").Value, " [")(0) & vbTab & ActiveSheet.Range("B12").Value & vbTab & "2571683" & MyBarCode & vbTab & ActiveSheet.Range("C200").Value & vbTab & ActiveSheet.Range("D200").Value & vbTab & ActiveSheet.Range("E200").Value & IIf(Sheet.CheckBox17, vbTab & ActiveSheet.Range("F9").Value, "")
Print #1, "2571683" & MyBarCode & "_532Block2.txt" & vbTab & "2571683" & MyBarCode & "_635Block2.txt" & vbTab & ActiveSheet.Range("C8").Value & " " & ActiveSheet.Range("C9").Value & vbTab & ActiveSheet.Range("C10").Value & vbTab & ActiveSheet.Range("C5").Value & vbTab & Split(ActiveSheet.Range("C11").Value, " [")(0) & vbTab & ActiveSheet.Range("C12").Value & vbTab & "2571683" & MyBarCode & vbTab & ActiveSheet.Range("C201").Value & vbTab & ActiveSheet.Range("D201").Value & vbTab & ActiveSheet.Range("E201").Value & IIf(Sheet.CheckBox17, vbTab & ActiveSheet.Range("F10").Value, "")
Print #1, "2571683" & MyBarCode & "_532Block3.txt" & vbTab & "2571683" & MyBarCode & "_635Block3.txt" & vbTab & ActiveSheet.Range("D8").Value & " " & ActiveSheet.Range("D9").Value & vbTab & ActiveSheet.Range("D10").Value & vbTab & ActiveSheet.Range("D5").Value & vbTab & Split(ActiveSheet.Range("D11").Value, " [")(0) & vbTab & ActiveSheet.Range("D12").Value & vbTab & "2571683" & MyBarCode & vbTab & ActiveSheet.Range("C202").Value & vbTab & ActiveSheet.Range("D202").Value & vbTab & ActiveSheet.Range("E202").Value & IIf(Sheet1.CheckBox17, vbTab & ActiveSheet.Range("F11").Value, "")
Print #1, "2571683" & MyBarCode & "_532Block4.txt" & vbTab & "2571683" & MyBarCode & "_635Block4.txt" & vbTab & ActiveSheet.Range("E8").Value & " " & ActiveSheet.Range("E9").Value & vbTab & ActiveSheet.Range("E10").Value & vbTab & ActiveSheet.Range("E5").Value & vbTab & Split(ActiveSheet.Range("E11").Value, " [")(0) & vbTab & ActiveSheet.Range("E12").Value & vbTab & "2571683" & MyBarCode & vbTab & ActiveSheet.Range("C203").Value & vbTab & ActiveSheet.Range("D203").Value & vbTab & ActiveSheet.Range("E203").Value & IIf(Sheet1.CheckBox17, vbTab & ActiveSheet.Range("F12").Value, "")
Close #1
file format
x
x 1 2 3 4
x 11 22 33 44
x --- --- --- ---
x Male Male Female Male
x --- --- --- ---
x 1 2 3 4 Please check the box to add comment
x 1111 2222 3333 4444 (checkbox17)
x xxx,xxx xxx,xxx xxx,xxx xxx,xxx comment1
x Male Male Female Male comment2
x xx xx xx xx comment3
x x x x x comment4
You must change:
ActiveSheet.Range("10").Value
into:
ActiveSheet.Range("F10").Value
But you can shorten down your code to:
If CheckBox17 Then
Worksheets("Sheet1").Range("F9:F12").value = ActiveSheet.Range("F9:F12").value
Else
Worksheets("Sheet1").Range("F9:F12") = "No Issues"
End If
I have a string that is read from a cell in Excel, which is something like this:
""Horace Lai" & vbNewLine & Date"
or this
"Chr(149) & "level 1" & vbNewLine & Chr(9) & Chr(149) & "level 2" & Chr(149) & "level 1" & vbNewLine & Chr(9) & Chr(149) & "level 2" & vbNewLine & Chr(9) & Chr(9) & Chr(149) & "level 3""
I would like to be able to evaluate these strings so that ""Horace Lai" & vbNewLine & Date" becomes:
Horace Lai
2014-06-20
So far I have tried ScriptControl without success. It doesn't seem to like it when I have double quotes for the string.
Sub testing()
Dim sc As ScriptControl
Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
MsgBox sc.Eval(""Horace Lai" & vbNewLine & Date")
End Sub
The MsgBox line becomes red and I cannot run it.
Any ideas? Thanks
-Horace
You specify JScript, instead:
Dim test As String, result As String
test = "Chr(149) & ""level 1"" & vbNewLine & Chr(9) & Chr(149) & ""level 2"" & Chr(149) & ""level 1"" & vbNewLine & Chr(9) & Chr(149) & ""level 2"" & vbNewLine & Chr(9) & Chr(9) & Chr(149) & ""level 3"""
Dim sc As Object
Set sc = CreateObject("ScriptControl")
sc.Language = "VBScript"
result = sc.Eval(test)
Debug.Print result
•level 1
•level 2•level 1
•level 2
•level 3
Firstly load the name into a variable i.e. name = """Horace Lai""" (this will contain the quote marks)
Then use the replace function to search for quotes in name name = Replace(name,"""","")
Then run the msgbox of MsgBox (name & vbNewLine & Date)
This should remove the extra " marks that you face
I have data in dataset which I am loopping to build up data for the email the data is as follows but I am using the following to produce the email using tabs but it doesnt see very iffiencet i can only use plain text is their a better way to get it to format nicer like using the datatable sizes or something
Dim dataForEmail As String = ""
Dim msg As String = ""
msg = "The Following Deliverys where processed for the Following Ordernumbers at " & DateTime.Now.ToString() & Chr(13)
dataForEmail = "Order Number" & vbTab & "BarCode" & vbTab & vbTab & vbTab & "Description" & vbTab & vbTab & vbTab & vbTab & vbTab & "Brand" & vbTab & vbTab & vbTab & "Size" & vbTab & "Colour" & vbTab & "Price" & vbTab & "RRP" & vbTab & vbTab & vbTab & "Qty" & Chr(13)
Dim totalcost As Decimal
If Not IsNothing(results) AndAlso Not IsNothing(results.Rows) _
AndAlso results.Rows.Count > 0 Then
For Each thisRow As DataRow In results.Rows
CreateDeliveryIncFileForGemini(thisRow)
totalcost = totalcost + thisRow.Item("RRPPrice")
dataForEmail = dataForEmail & BuildReportFoEmail(thisRow)
connection.ExecuteNonQuerySql(scriptBuilder.SetDeliveryStatus(2, 1, thisRow.Item("r3DeliveryId")))
Next
connection.ExecuteNonQuerySql(scriptBuilder.SetDeliveryStatus(1, 0))
dataForEmail = dataForEmail & vbCrLf & "Total Price " & totalcost.ToString()
SendEmailViaWebService(dataForEmail, cfb.EmailForDeliverys, cfb.FullNameForEmailSubject, msg)
End If
CloseConnection()