I wonder if you can help me modify this code ... it uses a dataset to look up against an indicator row to match field and complete a form for an indicator definition. This can be completed one or many times by modifying a column to yes or no.
It currently exports each indicator to a separate PDF - I would like the range of indicators selected combined as a single pdf - is this possible in the export? Possibly something like this to union print ranges?
Or if possible to paste each output as image to empty worksheet then export as pdf?
Sub print_selected_rows(inputData As Range, outputData As Range)
Dim data_columns, data_rows, filter_column, i, j
Dim ThisFile As Variant
data_rows = getArrayRows(inputData)
data_columns = getArrayColumns(inputData)
For i = 1 To data_columns
If (inputData.Cells(1, i).Value = "Select for report") Then
filter_column = i
Exit For
End If
Next
Sheets("Output").Visible = True
Sheets("Output").Select
For i = 1 To data_rows
If ((inputData.Cells(i, filter_column).Value = "yes") Or (inputData.Cells (i, filter_column).Value = "Yes") _
Or (inputData.Cells(i, filter_column).Value = "Y") Or (inputData.Cells(i, filter_column).Value = "y")) Then
'copy row data to output sheet
For j = 1 To data_columns
outputData.Cells(j, 3).Value = inputData.Cells(i, j).Value
Next
ThisFile = Application.GetSaveAsFilename( _
"abc" & " " & _
Range("selected_ID").Value, "PDF Files (*.pdf), *.pdf")
If VarType(ThisFile) = vbString Then
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=ThisFile, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
End If
End If
Next
Sheets("Introduction").Visible = True
Sheets("Introduction").Select
Sheets("Output").Visible = False
End Sub
I managed to work around this by copy and pasting as image to a new worksheet using the following code:
Sub print_selected_rows(inputData As Range, outputData As Range)
Dim data_columns, data_rows, filter_column, i, j, k
Dim ThisFile As Variant
k = 0
data_rows = getArrayRows(inputData)
data_columns = getArrayColumns(inputData)
For i = 1 To data_columns
If (inputData.Cells(1, i).Value = "Select for report") Then
filter_column = i
Exit For
End If
Next
Sheets("Output").Visible = True
Sheets("Output").Select
For i = 1 To data_rows
If ((inputData.Cells(i, filter_column).Value = "yes") Or (inputData.Cells (i, filter_column).Value = "Yes") _
Or (inputData.Cells(i, filter_column).Value = "Y") Or (inputData.Cells(i, filter_column).Value = "y")) Then
'copy row data to output sheet
For j = 1 To data_columns
outputData.Cells(j, 3).Value = inputData.Cells(i, j).Value
Next
With ThisFile
Sheets("Output").Range("A1:J55").CopyPicture xlScreen, xlBitmap
Worksheets("Sheet1").Paste _
Worksheets("Sheet1").Range("A1").Offset(k, 0)
k = k + 56
End With
End If
Next
Sheets("Introduction").Visible = True
Sheets("Introduction").Select
Sheets("Output").Visible = False
Sheets("Sheet1").Visible = False
End Sub
Related
I want to check if a cell in a sheet s4 has the same value for each cell in the sheet s1
So i tried to "stop" the Next c setting the c value as the previous cell, until the condition be true.
i put msgbox c.Value & "hiiiii" to check the c position, and is always the next cell.
Dim s1 As Worksheet
Dim s2 As Worksheet
Dim s3 As Worksheet
Dim s4 As Worksheet
Set s1 = ThisWorkbook.Sheets("test1")
Set s2 = ThisWorkbook.Sheets("test2")
Set s3 = ThisWorkbook.Sheets("test3")
Set s4 = ThisWorkbook.Sheets("test4")
Dim l As Integer
l = 8
lastrow = s4.Range("J" & s4.Rows.count).End(xlUp).row
Set rd = s4.Range("J2:J" & lastrow)
Set rf = s1.Range("A" & l)
For Each c In rd
msgbox c.Value & "hiiiii"
If rf.Value = "" Then: Exit For
If c.Value = rf.Value Then
s1.Range("B" & l).Value = c.Offset(, -1)
l = 8
Set rf = s1.Range("A" & l)
Else
l = l + 1
Set rf = s1.Range("A" & l)
Set c = c.Offset(-1, 0)
End If
Next c
There's a way to make it works?
Thank you
EDIT 1:
After some hours of breaking my head i changed the code and now it is working:
Dim l As Integer
Dim i As Integer
lastrow = s4.Range("J" & s4.Rows.count).End(xlUp).row
LastRow2 = s1.Range("A" & s1.Rows.count).End(xlUp).row
l = 8
i = 8
Set rd = s4.Range("J2:J" & lastrow)
Set rf = s1.Range("A" & i)
For Each c In rd
If c.Value <> rf.Value Then
For i = 8 To LastRow2
Set rf = s1.Range("A" & i)
If rf.Value = c.Value Then
rf.Offset(, 1).Value = c.Offset(, -1)
End If
Next i
Else
rf.Offset(, 1).Value = c.Offset(, -1)
End If
Next c
End Sub
A special thanks for Cyril and his tip about the another for options.
Screenshots/here refer:
CONSTRUCT
Fixed: comprises list of cells - press CMD button 'RUN' to select which values you want to compare against every populated cell of every other sheet.
This runs the macro Soln() (below).
test1-test3: arbitrary sheets comprising a medley of matching and mis-matched cell values/text etc. (contiguous / isolated cells etc.). Most content in test 1.
Audit_Trail: This will be removed/deleted if it exists when you run the macro so that a fresh sheet can be produced. This will display, for each target cell (selected step 1) and sheet (see 2) every cell (sheet/link/content) that did not match the respective target values.
CODE
(essential modules: Soln(), select cells - all the rest is 'bonus' - hope this works/helps you - assuming I understood issue correclty☺.)
Global addr(), target_cells(), s As String
Sub s_(new_txt)
Application.StatusBar = False
s = s & " --> " & new_txt
Application.StatusBar = s
End Sub
Sub Soln()
Application.StatusBar = False
s_ ("sub soln")
'Application.StatusBar = "Sub Soln()"
ReDim Preserve addr(0), target_cells(0)
Sheets("fixed").Move Before:=Sheets(1)
Call select_cells
Application.ScreenUpdating = False
m = -1
N_ = -1
K_ = -1
'Sheets(1).Activate
If sheet_exists("Audit_Trail") Then
Application.DisplayAlerts = False
Sheets("Audit_Trail").Delete
ThisWorkbook.Sheets.Add( _
After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)).Name = "Audit_Trail"
Application.DisplayAlerts = True
End If
With Sheets("Audit_Trail")
.Range("a1").Value = "Target_value"
.Range("b1").Value = "Sheet"
.Range("c1").Value = "Link/Content"
End With
For Each sh In ActiveWorkbook.Sheets
For Each yy In target_cells
sh.Activate
If (sh.Name = "fixed") Or (sh.Name = "Audit_Trail") Then
Exit For
'ActiveSheet.Next.Select
Else
On Error Resume Next
Selection.SpecialCells(xlCellTypeConstants, 23).Select
For Each c In Selection
If c.Value = yy Then
Resume Next
Else
addr_temp = Evaluate("ADDRESS(" & c.Row & "," & c.Column & ",1,1,""" & c.Worksheet.Name & """)")
With Sheets("Audit_Trail")
m = m + 1
.Range("a2").Offset(m).Value = yy
.Range("b2").Offset(m).Value = sh.Name
.Range("c2").Offset(m).Value = "=" & addr_temp
End With
End If
Next
End If
Next
Next
Application.ScreenUpdating = True
Application.StatusBar = False
Call pivot_summary
End Sub
Sub select_cells() '#Tim Williams (2011) - https://stackoverflow.com/questions/7353711/let-the-user-click-on-the-cells-as-their-input-for-an-excel-inputbox-using-vba
s_ ("sub select_cells()")
Dim rRange As Range
N_ = -1
On Error Resume Next
Application.DisplayAlerts = False
Sheets("fixed").Activate
Default_ = Sheets("fixed").Range("J2:J4").Address
Set rRange = Application.InputBox(Prompt:= _
"Please select range with cells you would like to compare against every other cell in this workbook.", Title:="SPECIFY RANGE", Default:=Default_, Type:=8)
Application.DisplayAlerts = True
If rRange Is Nothing Then
Exit Sub
Else
For Each c In rRange
N_ = N_ + 1
ReDim Preserve target_cells(0 To N_)
target_cells(N_) = c.Value
Next
End If
Return
End Sub
Function sheet_exists(sh As String) As Boolean
s_ ("sheet_exists()")
'Dim w As Excel.Worksheet
On Error GoTo eHandle
Set w = ThisWorkbook.Worksheets(sh)
sheet_exists = True
Exit Function
eHandle:
sheet_exists = False
End Function
'******not really required - could ignore *********'
Sub pivot_summary()
Range("a1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
Selection, Version:=8).CreatePivotTable TableDestination:= _
ActiveSheet.Range("g2"), TableName:="PivotTable5", _
DefaultVersion:=8
With ActiveSheet.PivotTables("PivotTable5").PivotFields("Target_value")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable5").PivotFields("Sheet")
.Orientation = xlRowField
.Position = 2
End With
ActiveSheet.PivotTables("PivotTable5").AddDataField ActiveSheet.PivotTables( _
"PivotTable5").PivotFields("Link/Content"), "Sum of Link/Content", xlSum
With ActiveSheet.PivotTables("PivotTable5").PivotFields("Sum of Link/Content")
.Caption = "Count of Link/Content"
.Function = xlCount
End With
ActiveSheet.PivotTables("PivotTable5").CompactLayoutRowHeader = "Target"
Range("H2").Select
ActiveSheet.PivotTables("PivotTable5").DataPivotField.PivotItems( _
"Count of Link/Content").Caption = "# mismatch"
Columns("G:H").Select
Selection.ColumnWidth = 11.27
Selection.Font.Name = "Brush Script MT"
Range("G22").Select
ActiveCell.FormulaR1C1 = "That's all folks! ?"
Range("G23").Select
ActiveWorkbook.Save
End Sub
GIF DEMO
OTHER INFO
To replicate for a single value, simply uapte the list in 1 (fixed) accordingly
This also creates a pivot in the Audit_Trail sheet summarises the extent of mismatches per sheet for each desired 'target value'.
What I want the Macro to accomplish:
I want the user to be able to fill in data from E2 to E9 on the spreadsheet. When the user presses the "Add Car" button the macro is supposed to be executed. The makro then should take the handwritten data, copy everything from E2:E9 and put it into a table that starts at with C13 and spans over 7 columns, always putting the new set of data in the next free row. It is also supposed to check for duplicates and give an alert while not overwriting the original set of data
So my problem is, that I want the Macro I'm writing to take the information put into certain cells and then copy them into a table underneath.
I'm starting the Macro like this
Sub addData()
Dim lastrow As Long, nextBlankRow As Long
lastrow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlPrevious, _
MatchCase:=False).Row
nextBlankRow = lastrow + 1
Here I try to define how the Macro is supposed to find the last empty cell and also define lastrow and nextBlankRow.
After that I'm starting with a simple If statement to see if the person has at least something in E2 on the same sheet.
If Range("E2") = "" Then
MsgBox "Wählen Sie ein KFZ aus!"
Range("E2").Select
Exit Sub
End If
This works. When I'm not putting something into E2 I get the textbox with the alert.
Anyway if the IF-Statement is not triggered to exit the sub the Macro is given the instructions to get the information and put it in the table below
Cells(nextBlankRow, 3) = Range("E2")
Cells(nextBlankRow, 4) = Range("E3")
Cells(nextBlankRow, 5) = Range("E4")
Cells(nextBlankRow, 6) = Range("E5")
Cells(nextBlankRow, 7) = Range("E6")
Cells(nextBlankRow, 8) = Range("E7")
Cells(nextBlankRow, 9) = Range("E8")
Here seems to be a problem that probably relates to me failing to define variables correctly?
Because the Macro finds the right row but only overwrites into that row. So it ignores the fact that it "should" skip to the nextBlankrow which I defined earlier as
nextBlankRow = lastrow + 1
In addition to that I also have a line of code inplace which is supposed to check for duplicates
Dim p As Long, q As Long
p = 13
q = p + 1
Do While Cells(p, 3) <> ""
Do While Cells(q, 3) <> ""
If Cells(p, 3) = Cells(q, 3) And Cells(p, 4) = Cells(q, 4) Then
MsgBox "Datensatz schon vorhanden!"
Range(Cells(q, 3), Cells(q, 9)).ClearContents
Else
q = q + 1
End If
Loop
p = p + 1
q = p + 1
Loop
End Sub
Which always gives a false return. So even if the same set of Data is copied twice into the same row (as it does) it only "refreshes" the data and doesn't say "you're not allowed to do that".
I'm at a loss here.
Here's the full code for ease of use
Sub addData()
Dim lastrow As Long, nextBlankRow As Long
lastrow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlPrevious, _
MatchCase:=False).Row
nextBlankRow = lastrow + 1
If Range("E2") = "" Then
MsgBox "Wählen Sie ein KFZ aus!"
Range("E2").Select
Exit Sub
End If
Cells(nextBlankRow, 3) = Range("E2")
Cells(nextBlankRow, 4) = Range("E3")
Cells(nextBlankRow, 5) = Range("E4")
Cells(nextBlankRow, 6) = Range("E5")
Cells(nextBlankRow, 7) = Range("E6")
Cells(nextBlankRow, 8) = Range("E7")
Cells(nextBlankRow, 9) = Range("E8")
Dim p As Long, q As Long
p = 13
q = p + 1
Do While Cells(p, 3) <> ""
Do While Cells(q, 3) <> ""
If Cells(p, 3) = Cells(q, 3) And Cells(p, 4) = Cells(q, 4) Then
MsgBox "Datensatz schon vorhanden!"
Range(Cells(q, 3), Cells(q, 9)).ClearContents
Else
q = q + 1
End If
Loop
p = p + 1
q = p + 1
Loop
End Sub
```![enter image description here](https://i.stack.imgur.com/dJozM.jpg)![enter image description here](https://i.stack.imgur.com/Q90Ah.jpg)
Please, test the next code:
Sub copyRangeOnLastEmptyRow()
Dim sh As Worksheet, arr, lastERow As Long, matchCel As Range
Set sh = ActiveSheet
arr = sh.Range("E2:E9").value
lastERow = sh.Range("C" & sh.rows.Count).End(xlUp).row + 1
If lastERow < 13 Then lastERow = 13
'check if the range has not been alredy copied:
Set matchCel = sh.Range("C13:C" & lastERow - 1).Find(WHAT:=sh.Range("E2").value, LookIn:=xlValues, Lookat:=xlWhole, MatchCase:=False)
If Not matchCel Is Nothing Then
MsgBox sh.Range("E2").value & " has been found in cell " & matchCel.Address & "."
'bring up the data of the existing row:
sh.Range("E3:E9").value = Application.Transpose(sh.Range(matchCel.Offset(0, 1), matchCel.Offset(0, 7)).value)
Exit Sub
End If
sh.Range("C" & lastERow).Resize(1, UBound(arr)).value = Application.Transpose(arr)
sh.Range("E2:E9").ClearContents
End Sub
I have a Userform with a listbox for which I am using conditional logic to determine output values to the sheet of selected or non-selected items in the listbox. The issue is that when the Textbox (Tbl_AliasName) is blank, the code executes this:
ElseIf .Selected(k) = True And Tbl_AliasName = vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Trim(Cells(2, 1).Value2) & "." & .Column(1, k)
But if Tbl_AliasName is not blank then the code does nothing, but it is supposed to do this:
ElseIf .Selected(k) = True And Tbl_AliasName <> vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Tbl_AliasName & "." & .Column(1, k)
I have used several variations of If statements, and non of which have worked.
Below is My Code:
Option Explicit
Public Tbl_AliasName As String
Tbl_AliasName = Trim(UserForm_Finder.txtConcat.Value)
Private Sub BtnConcat_Click()
Dim k As Long, lstbxRow As Long, LR As Long
lstbxRow = 1
'****************
'This if statement works perfectly
If (Cells(2, 1).Value2 = vbNullString Or Cells(2, 2).Value2 = vbNullString) _
And Tbl_AliasName = vbNullString Then
MsgBox "You must Search for a Table or Column first.", _
vbExclamation, "Error Encountered"
Exit Sub
ElseIf (UserForm_Finder.ListBx_TblsCols.ListCount = 0 And Tbl_AliasName <> vbNullString) Then
MsgBox "You must Search for a Table or Column first.", _
vbExclamation, "Error Encountered"
'(Cells(2, 1).Value2 = vbNullString Or Cells(2, 2).Value2 = vbNullString) And _
Exit Sub
End If
With UserForm_Finder.ListBx_TblsCols
For k = 0 To .ListCount - 1
'****************
This is where the problems begin
If .Selected(k) = False Then
MsgBox "You must Select 1 or more items from the list box.", _
vbExclamation, "Error Encountered"
Exit Sub
ElseIf .Selected(k) = True And Tbl_AliasName <> vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Tbl_AliasName & "." & .Column(1, k)
ElseIf .Selected(k) = True And Tbl_AliasName = vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Trim(Cells(2, 1).Value2) & "." & .Column(1, k)
End If
Next k
End With
End Sub
My goal is to do the following:
If a Textbox (Tbl_AliasName) is not blank and the user has selected one or more items in the listbox (ListBx_TbleCols) then concatenate the Tbl_AliasName to the selected items in the listbox
If Tbl_AliasName is blank, then use the value in Cells(2,1) to concatenate to the selected Items in the list box.
I have tried the following additions:
Dim LstBxItemSelected As Boolean
'This was placed in the for loop
LstBxItemSelected = True
'this was placed outside the for loop
If LstBxItemSelected = False Then
MsgBox "You must Select 1 or more items from the list box.", _
vbExclamation, "Error Encountered"
Exit Sub
End If
Is there a better way to tell if items are selected, because I feel that the way I have it structured in my loop, the code will throw the error if everything isn't selected? Thank you in advance for any ideas, answers, or suggestions!
Note: The Listbox is populated by the click of another button on the userform which calls the following sub:
Sub FillLstBxCols()
Dim ListBx_Target As MSForms.ListBox
Dim rngSource As Range
Dim LR As Long
If Cells(2, 1).Value2 <> vbNullString Then
LR = Worksheets("New TRAX").Cells(Rows.Count, 2).End(xlUp).Row
'Set reference to the range of data to be filled
Set rngSource = Worksheets("New Trax").Range("A" & 2 & ":" & "B" & LR)
'Fill the listbox
Set ListBx_Target = UserForm_Finder.ListBx_TblsCols
With ListBx_Target
.RowSource = rngSource.Address
End With
End If
End Sub
Hard to say without sample data and expected results, but I think this is what you're looking for:
Private Sub btnConcat_Click()
Dim ws As Worksheet
Dim bSelected As Boolean
Dim sConcat As String
Dim i As Long, lRowIndex As Long
Set ws = ActiveWorkbook.Sheets("New TRAX")
lRowIndex = 1
bSelected = False
sConcat = Trim(Me.txtConcat.Text)
If Len(sConcat) = 0 Then sConcat = Trim(ws.Cells(2, "A").Value)
If Len(sConcat) = 0 Then
MsgBox "You must Search for a Table or Column first.", vbExclamation, "Error Encountered"
Exit Sub
End If
For i = 0 To Me.ListBx_TblsCols.ListCount - 1
If Me.ListBx_TblsCols.Selected(i) Then
If bSelected = False Then
bSelected = True
ws.Range("C2", ws.Cells(ws.Rows.Count, "C")).Clear 'clear previous concat results (delete this line if not needed)
End If
lRowIndex = lRowIndex + 1
ws.Cells(lRowIndex, "C").Value = sConcat & "." & Me.ListBx_TblsCols.List(i)
End If
Next i
If bSelected = False Then MsgBox "Must select at least one item from the list"
End Sub
I am new to VBA and I could use a little bit of help for a program which I am struggling with for the past 3 days.
I have lot of data in a text file arranged as 3 columns. This data has to be parsed in an excel
The column 1 corresponds to the time, column 2 the variable and column 3 the value corresponding the variable .
The excel should parse the data such a way that column 1 has time, and column 2,3,4,5,6,7 the values corresponding to the variables in column 2 of the text file. and the values are in hex datei which has to be converted to decimal.
here is the code
Sub OpenText()
Dim MyFile As Variant
Dim TempWb As Workbook
Dim DestSh As Worksheet
Dim i As Long, p As Long, LimitRow As Long
Dim LastRow As Long
Dim LastRow2 As Long
p = 2
' Ask the user for the file name to open.
MyFile = Application.GetOpenFilename()
' Check for the Cancel button.
If MyFile = False Then Exit Sub
Application.ScreenUpdating = False
Set DestSh = ThisWorkbook.ActiveSheet
'Open the Text file with the OpenText method.
Workbooks.OpenText Filename:=MyFile, Origin:=xlWindows, _
StartRow:=1, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, _
Tab:=False, Semicolon:=False, Comma:=False, Space:=False, _
Other:=True, OtherChar _
:=";", FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, _
1), Array(6, 1), Array(7, 1)), _
DecimalSeparator:=".", ThousandsSeparator:=" ", TrailingMinusNumbers:= _
True
Set TempWb = ActiveWorkbook
LimitRow = 1048576 'Version Excel 2010
LastRow = Range("A" & LimitRow).End(xlUp).Row
If LastRow > 0 Then
For i = 1 To LastRow
If i = 1 Then
Cells(p, 1).Value = Cells(i, 1).Value
End If
Test = Cells(i, 2).Value
If Test = "0x005B" Then Cells(p, 2).Value = Cells(i, 3).Value Else _
If Test = "0x003E" Then Cells(p, 3).Value = Cells(i, 4).Value Else _
If Test = "0x0033" Then Cells(p, 4).Value = Cells(i, 3).Value Else _
If Test = "0x0039" Then Cells(p, 5).Value = Cells(i, 3).Value Else _
If Test = "0x003B" Then Cells(p, 6).Value = Cells(i, 3).Value Else _
If Test = "0x003D" Then Cells(p, 7).Value = Cells(i, 3).Value Else _
Next
End If
End Sub
The text file looks somewhat like this
2017-03-23_11-48-32.8;0x003E;0x1000
2017-03-23_11-48-32.8;0x0033;0x01F4
2017-03-23_11-48-32.8;0x0039;0x6720
2017-03-23_11-48-32.8;0x003B;0x6720
2017-03-23_11-48-32.8;0x003D;0x0050
2017-03-23_11-48-32.8;0x005E;0x1234ABCD
2017-03-23_11-48-33.1;0x0033;0x01F4
2017-03-23_11-48-33.1;0x0039;0x6720
2017-03-23_11-48-33.1;0x003B;0x6720
2017-03-23_11-48-33.4;0x003E;0x1000
2017-03-23_11-48-33.4;0x0033;0x01F4
2017-03-23_11-48-33.4;0x0039;0x6720
2017-03-23_11-48-33.4;0x003B;0x6720
2017-03-23_11-48-33.4;0x003D;0x0050
2017-03-23_11-48-33.4;0x005E;0x1234ABCD
2017-03-23_11-48-33.7;0x0033;0x01F4
2017-03-23_11-48-33.7;0x0039;0x6720
2017-03-23_11-48-34.0;0x003E;0x1000
2017-03-23_11-48-34.0;0x0033;0x01F4
2017-03-23_11-48-34.0;0x0039;0x6720
2017-03-23_11-48-34.0;0x003B;0x6720
2017-03-23_11-48-34.0;0x003D;0x0050
2017-03-23_11-48-34.0;0x005E;0x1234ABCD
2017-03-23_11-48-34.3;0x0033;0x01F4
2017-03-23_11-48-34.3;0x0039;0x6720
2017-03-23_11-48-34.3;0x003B;0x6720
2017-03-23_11-48-34.6;0x003E;0x1000
2017-03-23_11-48-34.6;0x0033;0x01F4
2017-03-23_11-48-34.6;0x0039;0x6720
2017-03-23_11-48-34.6;0x003B;0x6720
2017-03-23_11-48-34.6;0x003D;0x0050
2017-03-23_11-48-34.6;0x005E;0x1234ABCD
2017-03-23_11-48-34.9;0x0033;0x01F4
2017-03-23_11-48-34.9;0x0039;0x6720
2017-03-23_11-48-34.9;0x003B;0x6720
2017-03-23_11-48-35.2;0x003E;0x1000
2017-03-23_11-48-35.2;0x0033;0x01F4
2017-03-23_11-48-35.2;0x0039;0x6720
2017-03-23_11-48-35.2;0x003B;0x6720
2017-03-23_11-48-35.2;0x003D;0x0050
2017-03-23_11-48-35.2;0x005E;0x1234ABCD
2017-03-23_11-48-35.5;0x0033;0x01F4
2017-03-23_11-48-35.5;0x0039;0x6720
2017-03-23_11-48-35.5;0x003B;0x6720
And also the excel gets created in a different worksheet instead of the current worksheet.
Thanks in advance
Hope this resolve ur problem
Public Sub Append_text()
Set fso = New FileSystemObject
FLoc = "Y:\Macro\Test" & Format(Now(), "HHMMSS") & ".txt"
Set Stream = fso.OpenTextFile(FLoc, ForAppending, True)
x = 1 'Hoping the start point
Do Until Sheet1.Cells(x, 1) = "" 'U can use the end of file code here for looping till last row
Stream.Write Sheet1.Cells(x, 1) & ";" & Sheet1.Cells(x, 2) & ";" & Sheet1.Cells(x, 3) & vbNewLine
x = x + 1
Loop
End Sub
Public Sub Read_text()
Sheet2.Activate
Set fso = New FileSystemObject
Fname = Application.GetOpenFilename
x = 1
y = 1
Set Stream = fso.OpenTextFile(Fname, ForReading, True)
Do While Not Stream.AtEndOfStream
Str_text = Stream.ReadLine 'Perform your actions
rdtext = Split(Str_text, ";")
Sheet2.Cells(x, y) = rdtext(0)
Sheet2.Cells(x, y + 1) = rdtext(1)
Sheet2.Cells(x, y + 2) = rdtext(2)
x = x + 1
y = 1
Loop
Stream.Close
End Sub
Not directly on point to the problem but does answer Parsing Text file using VBA.
This is an auto-detect routine. You can add it to a customized tab by temporarily substituting a Sub line with no parameter and adding that. Then replace the Sub line with the real line with the optional parameters.
If you don't specify any of the Optional delimiters, this looks at the first 5 lines of the file and checks for common delimiters. For example, if any of those lines contains more than 8 pipes it assumes pipe is the delimiter.
BEWARE OF THE 'AUTOMATIC COMMA-SPLIT' ISSUE IN THE COMMENT. That is an EXCEL quirk, not a problem with .TextToColumns. Excel "remembers" choices previously made in the Data tab when someone used Get External Data or Data Tools > Text to Columns and might automatically re-perform that parsing when the file is opened.
Option Explicit
Sub Parse_any_delimited( _
Optional ByVal dlm_pipe As Boolean = False, _
Optional ByVal dlm_semi As Boolean = False, _
Optional ByVal dlm_comma As Boolean = False, _
Optional ByVal dlm_tab As Boolean = False, _
Optional ByVal dlm_carat As Boolean = False, _
Optional ByVal dlm_char As String = "", _
Optional ByVal no_delim_popup As Boolean = True)
' *** WARNING !!! ***
'
' The FIRST record that EXCEL will see DURING AN IMPORT CANNOT CONTAIN
' COMMAS! IF IT DOES, it interprets those as DELIMITERS and AUTOMATICALLY
' does a field split there BEFORE running any code! The result is that
' when all text SHOULD wind up in Cell A1, instead it gets parsed into
' cells at each comma. Then the REAL PARSE routine can only parse what
' IS in the Column A cells.
'
' The "comma parse" UPON LOADING occurs BEFORE any macro runs!
Dim i As Integer
Dim check_data As Boolean
check_data = False
Dim dlm_other As Boolean
dlm_other = False
Dim rcrd As Variant
Dim leave_for As Boolean
Dim have_delim As Boolean
'1 ****
If dlm_pipe Then
dlm_other = True
dlm_char = "|"
have_delim = True
'2 ****
ElseIf dlm_carat Then
dlm_other = True
dlm_char = "^"
have_delim = True
'3 ****
ElseIf dlm_tab Or dlm_semi Or dlm_comma Then
have_delim = True
'4 ****
Else
For i = 1 To 5 'Check first 5 records for common delimiters
leave_for = True
rcrd = Cells(i, "A").Value
If Count_Characters(rcrd, "|") > 5 Then
dlm_other = True
dlm_char = "|"
ElseIf Count_Characters(rcrd, ";") > 5 Then
dlm_semi = True
ElseIf Count_Characters(rcrd, ",") > 10 Then
dlm_comma = True
ElseIf Count_Characters(rcrd, vbTab) > 4 Then
dlm_tab = True
ElseIf Count_Characters(rcrd, "^") > 5 Then
dlm_other = True
dlm_char = "^"
Else
leave_for = False
End If
'===============
If leave_for Then
have_delim = True
Exit For
Else
have_delim = False
End If
Next i
'5 ****
End If
If have_delim = False Then
' B2 is checked because in certain cases Excel will
' AUTOMATICALLY parse data delimited by | or semicolons.
' When that happens, THIS sub sees it as "No delimiter Can't Parse"
' even though it HAS BEEN parsed.
If Cells(2, "B").Value = "" And no_delim_popup Then
MsgBox ("CAN'T PARSE - NO DELIMITER FOUND")
End If
Exit Sub
End If
' Stops "There's already data here--continue?"
Application.DisplayAlerts = False
Columns("A:A").Select
Selection.TextToColumns _
Destination:=Range("A1"), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=dlm_tab, _
Semicolon:=dlm_semi, _
Comma:=dlm_comma, _
Space:=False, _
Other:=dlm_other, _
OtherChar:=dlm_char
Cells.Select
Selection.Columns.AutoFit
Range("A1").Select
Application.DisplayAlerts = True
' Sub Parse_any_delimited()
End Sub
Function Count_Characters( _
ByVal str As Variant, _
ByVal chr As Variant) _
As Long
Count_Characters = Len(str) - Len(Replace(str, chr, ""))
End Function
the code below works 100%. It scans for a match in Column B and copies and renames a group of cells when a match is found. However the is a line For lRow = Sheets("HR-Calc").Cells(Cells.Rows.count, "b").End(xlUp).Row To 7 Step -1
Where the step -1 will scan row by row from the bottom of the sheet until a match is found. It would be much easier if the step was set to End.(xlUp) instead of -1. searching every row is overkill because of how the data is set up End.(xlUp) would massive cut down the run time.
Is something like this possible?
Sub Fill_CB_Calc()
M_Start:
Application.ScreenUpdating = True
Sheets("summary").Activate
d_input = Application.InputBox("select first cell in data column", "Column Data Check", Default:="", Type:=8).Address(ReferenceStyle:=xlA1, RowAbsolute:=True, ColumnAbsolute:=False)
data_col = Left(d_input, InStr(2, d_input, "$") - 1)
data_row = Right(d_input, Len(d_input) - InStr(2, d_input, "$"))
Application.ScreenUpdating = False
Sheets("summary").Activate
Range(d_input).End(xlDown).Select
data_last = ActiveCell.Row
If IsEmpty(Range(data_col & data_row + 1)) = True Then
data_last = data_row
Else
End If
For j = data_row To data_last
CBtype = Sheets("summary").Range(data_col & j)
Sheets("HR-Calc").Activate
For lRow = Sheets("HR-Calc").Cells(Cells.Rows.count, "b").End(xlUp).Row To 7 Step -1
If Sheets("HR-Calc").Cells(lRow, "b") = CBtype Then
CBend = Sheets("HR-Calc").Range("C" & lRow).End(xlDown).Row + 1
Sheets("HR-Calc").Rows(lRow & ":" & CBend).Copy
CBstart = Sheets("HR-Calc").Range("c50000").End(xlUp).Row + 2
ActiveWindow.ScrollRow = CBstart - 8
Sheets("HR-Calc").Range("A" & CBstart).Insert Shift:=xlDown
CBold = Right(Range("c" & CBstart), Len(Range("C" & CBstart)) - 2)
box_name = Sheets("summary").Range(data_col & j).Offset(0, -10)
CBnew = Right(box_name, Len(box_name) - 2) & "-" ' <--this is custom and can be changed based on CB naming structure
If CBnew = "" Or vbCancel Then
End If
CBend2 = Range("c50000").End(xlUp).Row - 2
Range("C" & CBstart + 1 & ":" & "C" & CBend2).Select
Selection.Replace What:=CBold & "-", Replacement:=CBnew, LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Range("C" & CBstart).FormulaR1C1 = "CB" & Left(CBnew, Len(CBnew) - 1)
GoTo M_Start2
Else
End If
Next lRow
M_Start2:
Next j
YN_result = MsgBox("Fill info for another block/inverter?", vbYesNo + vbExclamation)
If YN_result = vbYes Then GoTo M_Start
If YN_result = vbNo Then GoTo jumpout
jumpout:
' Sheets("summary").Range(d_input).Select
Application.ScreenUpdating = True
End Sub
I'm not sure if this will help but I've had a great performance increase with pulling the entire range you need to loop through into a variant array and then looping through the array. If I need to loop through large data sets, this method has worked out well.
Dim varArray as Variant
varArray = Range(....) 'set varArray to the range you're looping through
For y = 1 to uBound(varArray,1) 'loops through rows of the array
'code for each row here
'to loop through individual columns in that row, throw in another loop
For x = 1 to uBound(varArray, 2) 'loop through columns of array
'code here
Next x
Next y
You can also define the column indexes prior to executing the loop. Then you only need to execute the you need to pull those directly in the loop.
'prior to executing the loop, define the column index of what you need to look at
Dim colRevenue as Integer
colRevenue = 5 'or a find function that searches for a header named "Revenue"
Dim varArray as Variant
varArray = Range(....) 'set varArray to the range you're looping through
For y = 1 to uBound(varArray,1) 'loops through rows of the array
tmpRevenue = CDbl(varArray(y, colRevenue))
Next y
Hope this helps.
Look at doing a .find from the bottom up.
Perform a FIND, within vba, from the bottom of a range up
That will eliminate the need to do the for loop from the last row to the first occurrence of the value you want to locate.