Insert string into a specific line in a text file - excel

I have an excel sheet with strings in the rows.
I have a txt file.
I already have the specific number of lines I want to insert the strings.
but when I use "write" it deletes all and then inserts the string.
How can I insert a string into a specific line in a text file? i'll use a loop to open and close all the txt files.
the code works. just need to put the string in the txt file.
p.s the note is in Hebrew.
Sub SearchTextFile()
'--------------------------------------------------------------------------------------------------úçéìú øéöú ÷åã
Dim Start, Finish, TotalTime As Date
Start = Timer
'--------------------------------------------------------------------------------------------------áéèåì çéùåáéí åòãëåðé îñê åäúøàåú
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
'--------------------------------------------------------------------------------------------------äçæøú çéùåáéí åòãëåðé îñê åäúøàåú
'Application.Calculation = xlCalculationAutomatic
'Application.ScreenUpdating = True
'Application.DisplayAlerts = True
'Application.AskToUpdateLinks = True
Dim strLine1, strLine2, strSearch1, strSearch2, Mid1, Mid2 As String
Dim i, j, z, h As Integer
Dim x, LineCount1, LineCount2 As Long
Dim blnFound As Boolean
x = 2
LineCount1 = 0
h = 0
Do Until IsEmpty(Cells(x, 2))
myFileCOMPANY = "L:\" & Cells(x, 2) & "\COMPANY.bat" 'áãé÷ä øàùåðéí äàí îñôø äçáøä ÷ééí áëìì
If Not Dir(myFileCOMPANY) = "" Then 'àí ìà øé÷
strFileName = "L:\" & Cells(x, 2) & "\COMPANY.bat" 'ðúéá - àéôä ìçôù
strSearch1 = Cells(x, 7) 'îä ìçôù
strSearch1 = "If Exist Dfile" & Format(strSearch1, "000") 'ùéðåé ôåøîè
i = FreeFile
On Error Resume Next
Open strFileName For Input As #i
Do While Not EOF(i)
LineCount1 = LineCount1 + 1
Line Input #i, strLine1
If InStr(1, strLine1, strSearch1, vbBinaryCompare) > 0 Then 'äáéã÷ä òöîä äàí äè÷ñè ùîçôùéí ÷ééí áùåøä äæå
strSearch2 = "pz-"
Line Input #i, strLine2
For j = 1 To 4
If InStr(1, strLine2, strSearch2, vbBinaryCompare) + 1 > 0 Then 'äáéã÷ä òöîä äàí äè÷ñè ùîçôùéí ÷ééí áùåøä äæå
Cells(x, 11) = Cells(x, 2) 'îñôø çáøä
Cells(x, 12) = Format(Cells(x, 7), "000") 'îñôø úú
Cells(x, 13) = LineCount1 + j 'îñôø ùåøä
blnFound = True
Cells(x, 14) = Len(strLine2) 'àåøê ùåøä
Cells(x, 15) = "1." & strSearch1 & " 2." & strSearch2 'úå ùàåúå çéôùå
Cells(x, 16) = strLine2 'è÷ñè áùåøä ìôðé
Mid1 = Mid(Cells(x, 16), Cells(x, 14) - 12, 5)
Cells(x, 17) = Cells(x, 16) & " " & Mid1 & Cells(x, 3) & ".pdf"
For z = 1 To 10 'áîéãä åéù òåã îàåúä äçáøä åàåúå äúú àæ ëàï äúåñôåú ëøèéñéí ðöáøéí
If Cells(x, 7) = Cells(x + z, 7) And Cells(x, 2) = Cells(x + z, 2) Then
Cells(x + z, 16) = Cells(x + h, 17)
Mid2 = Mid(Cells(x + z, 16), Cells(x, 14) - 12, 5)
Cells(x + z, 17) = Cells(x + z, 16) & " " & Mid2 & Cells(x + z, 3) & ".pdf"
h = h + 1
End If
Next z
Exit For
End If
Next j
Open myFileCOMPANY For Output As #i
Write #i, "dfgdfg" 'Cells(x + z, 17)
Exit Do
Else: Cells(x, 11) = Cells(x, 2)
Cells(x, 12) = Cells(x, 7)
Cells(x, 15) = "Dfile" & Format(Cells(x, 7), "000") & " not found"
End If
Loop
Close #i
LineCount1 = 0
Else: Cells(x, 11) = "No folder number " & Cells(x, 2)
End If
x = x + h
h = 0
x = x + 1
Loop
'--------------------------------------------------------------------------------------------------äçæøú çéùåáéí åòãëåðé îñê åäúøàåú
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.AskToUpdateLinks = True
'--------------------------------------------------------------------------------------------------æîï ñéåí øéöú ÷åã åçéùåá
Finish = Timer
TotalTime = Format((Finish - Start) / 86400, "hh:mm:ss")
MsgBox ("äãå''ç îåëï" & vbNewLine & "æîï øéöú ÷åã: " & TotalTime)
End Sub

Not sure what code you have tried. It would be easier if you included your code.
You could try using:
If Application.Options.Overtype Then
Application.Options.Overtype = False
End If
If you are trying to add a line to the end of your document you can use the following code:
Function WordAddEnd()
Dim objWord As Object, objDoc As Object, objSelection As Object
Dim endpoint As Integer, moveit As Integer
Dim FileString As String
endpoint = 6
moveit = 0
FileString = "C:\location\folder\document.docx"
Set objWord = CreateObject("Word.Application")
Onerror resumenext
'change error handling
Set objDoc = objWord.documents.Open(FileString)
Set objSelection = objWord.Selection
With objSelection
.EndKey endpoint, moveit
'finds end point of document
.typeparagraph
'goes to next line (like pressing the enter key)
.TypeText ("It's some text you wanted")
'your text here
End With
objWord.documents.Close
End Function
If the document in question is already open, there will be an error so you'll need some error handling in here.

Related

My code contains two buttons, but only one button works correctly

First, I want to state, that I am by far no professional, maybe an amateur, so I would really appreciate, if you could give some basic feedback on my coding if you want of course. I think, that would be a good way of learning to code :)
I am a logistics student and I have learned quite a bit of vba coding in class we had last year.
I started as a working student last week and I have to track my hours, so I tried to code a programm in VBA, which
opens an excel worksheet, the user types in the starting day month and year, in the "non-american" way --> 01.09.2022 instead of 09/01/2022.
After that, the vba automatically fills in a table with the dates and the weekdays according to the given date. I added some additional codings like graying out all weekends and stuff.
My problem lies in the buttons. I used two buttons, but only one of them is working.
The button should run the exact same sub it is placed in, to reactivate the code, when the month passed.
Unfortunately somehow, it doesnt recognise the button as a button, I think the macro wont bind to it?
I have a second button, which mutliplies the hours worked with an hour-based salary the user enters, to see how much money was made :)
My code:
Sub Tabelle()
Worksheets.Add
Dim Eingabe As String, T As Integer, Tag As Integer, Z As Long, b As Excel.Shape, Lohn As Double, btn As Excel.Shape
Eingabe = InputBox("Geben Sie bitte das Anfangsdatum des Monats an, z.B. 01.09.2022")
ActiveSheet.Name = "Zeiterfassung " & Eingabe
'Tagesanzahl für eingegebenen Monat finden
If Mid(Eingabe, 4, 2) = "01" Then T = 31
If Mid(Eingabe, 4, 2) = "02" Then T = 29
If Mid(Eingabe, 4, 2) = "03" Then T = 31
If Mid(Eingabe, 4, 2) = "04" Then T = 30
If Mid(Eingabe, 4, 2) = "05" Then T = 31
If Mid(Eingabe, 4, 2) = "06" Then T = 30
If Mid(Eingabe, 4, 2) = "07" Then T = 31
If Mid(Eingabe, 4, 2) = "08" Then T = 31
If Mid(Eingabe, 4, 2) = "09" Then T = 30
If Mid(Eingabe, 4, 2) = "10" Then T = 31
If Mid(Eingabe, 4, 2) = "11" Then T = 30
If Mid(Eingabe, 4, 2) = "12" Then T = 31
'Datum erstellen in Spalte 1
Tag = Left(Eingabe, 2)
For i = 3 To (T + 2)
Cells(i, 1) = Format(Tag, "00") & "." & Mid(Eingabe, 4, 99)
Tag = Tag + 1
Next i
'Wochentage für jedes Datum eintragen in Spalte 2
i = 3
Do While Cells(i, 1) <> ""
If Weekday(Cells(i, 1)) = 1 Then Cells(i, 2) = "Sonntag"
If Weekday(Cells(i, 1)) = 2 Then Cells(i, 2) = "Montag"
If Weekday(Cells(i, 1)) = 3 Then Cells(i, 2) = "Dienstag"
If Weekday(Cells(i, 1)) = 4 Then Cells(i, 2) = "Mittwoch"
If Weekday(Cells(i, 1)) = 5 Then Cells(i, 2) = "Donnerstag"
If Weekday(Cells(i, 1)) = 6 Then Cells(i, 2) = "Freitag"
If Weekday(Cells(i, 1)) = 7 Then Cells(i, 2) = "Samstag"
i = i + 1
Loop
Z = 3
Do While Cells(Z, 2) <> ""
If Cells(Z, 2) = "Samstag" Or Cells(Z, 2) = "Sonntag" Then
Cells(Z, 1).Interior.ColorIndex = 6
Cells(Z, 2).Interior.ColorIndex = 6
Cells(Z, 3).Interior.ColorIndex = 6
Cells(Z, 4).Interior.ColorIndex = 6
Cells(Z, 5).Interior.ColorIndex = 6
Cells(Z, 6).Interior.ColorIndex = 6
End If
Z = Z + 1
Loop
'Code für Stunden gearbeitet
For i = 3 To (T + 2)
Cells(i, 5) = "=" & "(D" & i & "-" & "C" & i & ") * 24"
Next i
'Button für neuen Monat
Set b = ActiveSheet.Shapes.AddFormControl(xlButtonControl, 265, 500, 100, 50)
b.OnAction = "Tabelle"
b.OLEFormat.Object.Text = "Nächster Monat"
Set btn = ActiveSheet.Shapes.AddFormControl(xlButtonControl, 300, 470, 100, 50)
b.OnAction = "Testing"
b.OLEFormat.Object.Text = "Entgelt aktualisieren"
Range("C34").FormulaLocal = "=Summe(E3:E33)-Summe(F3:F33)"
Range("A35") = "Entgelt"
Lohn = InputBox("Geben Sie ihren Stundenlohn ein!")
Range("A40") = "Stundenlohn"
Range("B40") = Format(Lohn, "00.00 €")
Range("A3:F" & T + 2).BorderAround LineStyle:=xlContinuous, Weight:=xlThick
Range("A2:F2").BorderAround LineStyle:=xlContinuous, Weight:=xlThick
Range("A2") = "Datum"
Range("B2") = "Tag"
Range("C2") = "Von"
Range("D2") = "Bis"
Range("E2") = "Std."
Range("F2") = "Pause in Std."
Range("A34") = "Stunden gesamt"
End Sub
Sub Testing()
Range("C35") = Format(Left(Range("C34"), 2) * Range("B40"), "#,#00.00 €")
End Sub
Picture of the Worksheet 1
Picture of the Worksheet 2
The lower button is working btw.
Please, try the next optimized code:
Sub Tabelle()
Dim ws As Worksheet, rngA As Range, rngB As Range, Eingabe As String
Dim minD As Date, maxD As Date, arrD, arrTags, arrCol, rngCol As Range, i As Long
Dim boolYearEnd As Boolean: If Month(Date) = 12 Then boolYearEnd = True
Worksheets.Add
Set ws = ActiveSheet 'set the added sheet
'it proposes the first day of the next month (it ca be easily modified):
Eingabe = InputBox("Geben Sie bitte das Anfangsdatum des Monats an, z.B. 01.09.2022", _
"Date input", Format(DateSerial(IIf(boolYearEnd, Year(Date) + 1, Year(Date)), _
IIf(boolYearEnd, 1, Month(Date) + 1), 1), "dd.mm.yyyy"))
If IsDate(Eingabe) Then
minD = DateValue(Eingabe) ' if a correct input, it is converted to date
Else
MsgBox "The input (" & Eingabe & ") is not a correct date, please enter a correct one in the recommended format...": Exit Sub
End If
maxD = WorksheetFunction.EoMonth(minD, 0) 'set the end of the above month entered
arrD = Evaluate("row(" & CLng(minD) & ":" & CLng(maxD) & ")") 'create an array of the necessary Date
Set rngA = Range("A3").Resize(UBound(arrD), 1) 'set the range where to drop the array content
Application.ScreenUpdating = False: Application.Calculation = xlCalculationManual 'Optimization to make the code faster
With rngA
With .rows(1).Resize(, 6).Offset(-1) 'add headers and format a little:
.Value = Array("Datum", "Tag", "Von", "Bis", "Std.", "Pause in Std.")
.BorderAround LineStyle:=xlContinuous, Weight:=xlThick
.Font.Bold = True
.HorizontalAlignment = xlCenter
.Borders(xlInsideVertical).Weight = xlThick
End With
.Value = arrD
.NumberFormat = "dd.mm.yyyy"
.Offset(, 1).Formula2 = "=TagName(" & .cells(1).Address(0, 0) & ")" 'fill also the days name in the next column
.Offset(, 4).Formula2 = "=(D" & .cells(1).row & "-C" & .cells(1).row & ")*24" 'place the formula to calculate hours difference
.Offset(, 1).Value = .Offset(, 1).Value 'transform formula in value
Set rngB = .Offset(, 1) 'set rngB as next column Offset
End With
arrCol = rngB.Value2 'place B:B column in an array, for faster iteration/processing
For i = 1 To UBound(arrCol)
If arrCol(i, 1) = "Samstag" Or arrCol(i, 1) = "Sonntag" Then
addToRange rngCol, rngB(i).Offset(, -1).Resize(, 6) 'create a Union range to color it at once (very fast)
End If
Next i
If Not rngCol Is Nothing Then rngCol.Interior.ColorIndex = 6
'insert the two necessary buttons:
With ws.Shapes.AddFormControl(xlButtonControl, 270, 500, 100, 50)
.OnAction = "Tabelle": .OLEFormat.Object.Text = "Nächster Monat"
End With
With ws.Shapes.AddFormControl(xlButtonControl, 270, 440, 100, 50)
.OnAction = "Testing": .OLEFormat.Object.Text = "Entgelt aktualisieren"
End With
'add other necessary data:
ws.Range("A35") = "Entgelt"
ws.Range("C34").FormulaLocal = "=Summe(E3:E33)-Summe(F3:F33)"
Dim Lohn As String
Lohn = InputBox("Geben Sie ihren Stundenlohn ein!")
ws.Range("A40").Value = "Stundenlohn"
ws.Range("B40").Value = Format(Lohn, "00.00 €")
With rngA.Resize(, 6) 'a little format for the 6 involved columns
.EntireColumn.AutoFit
.BorderAround LineStyle:=xlContinuous, Weight:=xlThick
.Borders(xlInsideVertical).Weight = xlThin
End With
Application.ScreenUpdating = True: Application.Calculation = xlCalculationAutomatic 'Optimization to make the code faster
MsgBox "Ready..."
End Sub
Function TagName(d As Date) As String 'function to return the day name for a specific date
Dim arrT: arrT = Split("Sonntag,Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag", ",")
TagName = arrT(WorksheetFunction.Weekday(d, vbSunday) - 1)
End Function
Private Sub addToRange(rngU As Range, rng As Range) 'function to create the Union range
If rngU Is Nothing Then
Set rngU = rng
Else
Set rngU = Union(rngU, rng)
End If
End Sub

I have an error of range using Useform "Method_Default of object range failed

I am creating an useform to create, modify, search and delete data.
when I'm running the code to create data, it shows the error:
Run-time error '-2147417848(80010108)':
Method'_Default' of object 'range'failed.
I have tried to change the object (name of te worksheet.) for (activesheet.) activating the sheet where I am registering the data I want to add but still not working.
The code has several procedures, but I'm having trouble just when I am creating new data
At the beginning it worked well but now it has this issue. I am new programming.
The code fails in this area
S
et oCelda = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1)
oCelda = consecutivo
complete code as follow
Private Sub Cmb_Registro_Click()
Dim oCelda As Range
Dim bCheck As Boolean
Dim Consecutivo as Double, file As long, Col As long, Final As Long
Worksheets("Data").Activate
bCheck = Txt_Fecha <> "" And Cbo_Categoria <> "" And Cbo_Subcategoria <> "" And Txt_Monto <> "" _
And Cbo_Periodo <> "" And Txt_Descripcion <> ""
Col = 1
fila = 2
Cbo_Periodo.Enabled = False
Do While ActiveSheet.Cells(fila, Col) <> Empty
fila = fila + 1
Loop
Final = fila
Consecutivo = Val(ActiveSheet.Cells(Final - 1, Col))
If Consecutivo = 0 Then
consecutivo = 1
Else
consecutivo = ActiveSheet.Cells(Final - 1, Col) + 1
End If
If bCheck And optIngreso Then
*Set oCelda = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1)
oCelda = consecutivo*
oCelda.Offset(0, 1) = CDate(Txt_Fecha)
oCelda.Offset(0, 2) = CLng(Txt_Monto)
oCelda.Offset(0, 3) = lblIngreso.Caption
oCelda.Offset(0, 4) = Txt_Descripcion
oCelda.Offset(0, 5) = Cbo_Categoria
oCelda.Offset(0, 6) = Cbo_Subcategoria
oCelda.Offset(0, 7) = Cbo_Periodo
MsgBox "Registro completo"
Unload Me
ElseIf bCheck And optEgreso Then
*Set oCelda = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1)
oCelda = consecutivo*
oCelda.Offset(0, 1) = CDate(Txt_Fecha)
oCelda.Offset(0, 2) = CLng(Txt_Monto)
oCelda.Offset(0, 3) = lblEgreso.Caption
oCelda.Offset(0, 4) = Txt_Descripcion
oCelda.Offset(0, 5) = Cbo_Categoria
oCelda.Offset(0, 6) = Cbo_Subcategoria
oCelda.Offset(0, 7) = Cbo_Periodo
MsgBox "Registro completo"
Unload Me
Else
MsgBox "Faltan datos"
End If
Worksheets("Inicio").Activate
End Sub

Shuffling a 2D array

I have the follow script to put a list of people with there know skills in an array and then match the first match with a customer with the same skill. Every time it runs the results are the same. I would like to have it be a random order of the array, but keeping the two columns in the array together. How can I shuffle(rearrange) the array that keeps the rows in the array the same? Or would it be better to erase the array, randomly sort the columns and set the array back up?
Sub Assign()
Dim arOne()
ReDim arOne(1000, 15)
Dim o As Integer
Dim p As Integer
Dim StartTime As Double
Dim MinutesElapsed As String
p = 0
o = 0
For i = 2 To 920
If Cells(i, 12).Value <> Cells(i - 1, 12) Then
p = p + 1
arOne(p, 0) = Cells(i, 12).Value
arOne(p, 1) = Cells(i, 13).Value
o = 2
Else
arOne(p, o) = Cells(i, 13).Value
o = o + 1
End If
Next
For i = 2 To 612
For o = LBound(arOne, 1) + 1 To UBound(arOne, 1)
If arOne(o, 0) <> "" Then
iUsed = Application.WorksheetFunction.CountIf(Range("C2:C" & i), "=" & arOne(o, 0))
If iUsed < Application.WorksheetFunction.VLookup(arOne(o, 0), Range("Q2:R62"), 2, False) Then
For j = LBound(arOne, 2) + 1 To UBound(arOne, 2)
If arOne(o, j) = Cells(i, 2).Value Then
Cells(i, 3).Value = arOne(o, 0)
ActiveSheet.Calculate
GoTo NextIR
End If
Next j
End If
End If
Next o
NextIR:
Next i
End Sub
Multiple loops and multiple access to range objects makes your code very, very slow (I don't know if performance is important).
I would read all necessary data to arrays and use filter and rnd to get a random person with the relevant skill:
Option Explicit
Sub PeopleBusiness()
Dim People, Customers, FilterArray
Dim I As Long, Idx As Long
People = Application.Transpose([L2:L920 & "|" & M2:M8])
Customers = Range("A2:C612").Value2
For I = 1 To UBound(Customers, 1)
FilterArray = Filter(People, Customers(I, 2))
If UBound(FilterArray) > -1 Then
Idx = Round(Rnd() * UBound(FilterArray), 0)
Customers(I, 3) = Left(FilterArray(Idx), InStr(1, FilterArray(Idx), "|") - 1)
End If
Next I
Range("A2:C612").Value = Customers
End Sub
I was able to get done what I needed by erasing the array and redimming it after sorting the data based on a rand() number in the table. It takes about 15 minutes to run 7000 assignment but it is a lot better than 7+ hours it takes to do manually.
Sub Assign()
Dim arOne()
ReDim arOne(1000, 15)
Dim o As Integer
Dim p As Integer
Dim StartTime As Double
Dim MinutesElapsed As String
Application.Calculation = xlAutomatic
StartTime = Timer
NextIR:
ReDim arOne(1000, 15)
p = 0
o = 0
QAlr = Sheets("Sheet1").Range("L" & Rows.Count).End(xlUp).Row
For I = 2 To QAlr
If Cells(I, 12).Value <> Cells(I - 1, 12) Then
p = p + 1
arOne(p, 0) = Cells(I, 12).Value
arOne(p, 1) = Cells(I, 13).Value
o = 2
Else
arOne(p, o) = Cells(I, 13).Value
o = o + 1
End If
Next
AQAlr = Sheets("Sheet1").Range("C" & Rows.Count).End(xlUp).Row
AgtLr = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
For I = AQAlr + 1 To AgtLr
For o = LBound(arOne, 1) + 1 To UBound(arOne, 1)
If arOne(o, 0) <> "" Then
iUsed = Application.WorksheetFunction.CountIf(Range("C2:C" & I), "=" & arOne(o, 0))
If iUsed < Application.WorksheetFunction.VLookup(arOne(o, 0), Range("Q2:R62"), 2, False) Then
For j = LBound(arOne, 2) + 1 To UBound(arOne, 2)
If arOne(o, j) = Cells(I, 2).Value Then
Cells(I, 3).Value = arOne(o, 0)
ActiveSheet.Calculate
Erase arOne()
ActiveWorkbook.Worksheets("Sheet1").ListObjects("Table1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").ListObjects("Table1").Sort.SortFields.Add _
Key:=Range("Table1[[#All],[Random '#]]"), SortOn:=xlSortOnValues, Order:= _
xlDescending, DataOption:=xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Sheet1").ListObjects("Table1").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
GoTo NextIR
End If
Next j
End If
End If
Next o
Next I
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
MsgBox "Assignments completed in " & MinutesElapsed & " minutes", vbInformation
End Sub
Not entirely sure I got your set-up right but you can try this:
Option Explicit
Sub Assign()
Randomize
Range("C2", Range("C" & Rows.Count).End(xlUp)).ClearContents
Dim R1 As Range: Set R1 = Range("L2:M920") 'People skill table
Dim R2 As Range: Set R2 = Range("A2:B612") 'Cusotmers skill talbe
Dim D0 As Object: Set D0 = CreateObject("scripting.dictionary")
Dim i As Integer, j As Integer, Rand as Integer
For i = 1 To R2.Rows.Count
Rand = Int(R1.Rows.Count * Rnd + 1)
For j = 1 To R1.Rows.Count
If R1.Cells(Rand, 2) = R2(i, 2) And Not D0.exists(Rand) Then
R2.Cells(i, 2).Offset(0, 1) = R1(Rand, 1)
D0.Add Rand, Rand
Exit For
End If
Rand = (Rand Mod R1.Rows.Count) + 1
Next j
Next i
End Sub
The idea is to check the people skill list starting from a random point and making sure a key is not used twice.
EDIT:
According to your comment I assume a "people / skill" can then be assigned more than once as there are 7000+ customers ?
Code below randomly assign with a fairly good distribution 1500 peoples to 7000 customers in +/- 1 second.
Have a try and see if you can adapt it to your project.
Option Explicit
Sub Assign()
Application.ScreenUpdating = False
Dim Start: Start = Timer
Randomize
Range("C2:C99999").ClearContents
Dim D1 As Object
Dim R1 As Range: Set R1 = Range("L2", Range("M" & Rows.Count).End(xlUp))
Dim R2 As Range: Set R2 = Range("A2", Range("B" & Rows.Count).End(xlUp))
Dim T1: T1 = R1
Dim T2: T2 = R2
Dim T3()
Dim a As Integer: a = 1
Dim i As Integer, j As Integer, k As Integer, Rnd_Val As Integer, j_loop As Integer
For i = 1 To (Int(R2.Rows.Count / R1.Rows.Count) + 1)
Set D1 = CreateObject("scripting.dictionary")
For j = (R1.Rows.Count * i - R1.Rows.Count + 1) To R1.Rows.Count * i
ReDim Preserve T3(1 To j)
Rnd_Val = Int(Rnd * R1.Rows.Count + 1)
For k = 1 To R1.Rows.Count
If T1(Rnd_Val, 2) = T2(j, 2) And Not D1.exists(Rnd_Val) And T3(j) = "" Then
T3(j) = T1(Rnd_Val, 1)
D1.Add Rnd_Val, Rnd_Val
Exit For
End If
Rnd_Val = (Rnd_Val Mod R1.Rows.Count) + 1
Next k
If T3(j) = "" Then
For k = 1 To R1.Rows.Count
If T1(Rnd_Val, 2) = T2(j, 2) Then
T3(j) = T1(Rnd_Val, 1)
Exit For
End If
Rnd_Val = (Rnd_Val Mod R1.Rows.Count) + 1
Next k
End If
a = a + 1
If a > R2.Rows.Count Then GoTo EndLoop
Next j
Set D1 = Nothing
Next i
EndLoop:
Range("C2").Resize(UBound(T3), 1) = Application.Transpose(T3)
Debug.Print Timer - Start
Application.ScreenUpdating = True
End Sub

EXCEL VBA FIND Value and then sum and then delete other row

enter image description here[enter image description here][2]Hi,
I have an issue and hopefully someone can help. I have an Excel sheet and I Need to check if starting from last row if the same value as in column 4 from last row exists somewhere above, but condition is, that only if column 1 and column 2 are same and not in column 3 is the word "SK" or "SV" and then I Need to sum the values in column 7 and concaternate column 3 and column 6 and just Keep one line and the other which were the base of this calculation must be deleted.
Attached you will find the screenshots. First how the Excel file Looks like before processing and next screenshot how it should look like afterwards.
enter image description here
Here is the code:
Sub combine_data()
Dim vLastRow As Integer
Dim Col_A_Str As String
Dim Col_B_Str As String
Dim r As Integer
Dim vDatarow As Integer
Dim vCodeStr3 As String
Dim vCodeStr6 As String
Dim vTotal As Double
Dim Col_D_Str As String
vLastRow = Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
Col_A_Str = ""
Col_B_Str = ""
r = 1
vDatarow = 0
vCodeStr3 = ""
vCodeStr6 = ""
vTotal = 0
Col_D_Str = ""
Col_A_Str = Trim(Cells(vLastRow, 1))
Col_B_Str = Trim(Cells(vLastRow, 2))
Col_D_Str = Trim(Cells(vLastRow, 4))
Do Until r = vLastRow
DoEvents
If Trim(Cells(r, 4)) = Col_D_Str Then
If Trim(Cells(r, 1)) = Col_A_Str Then
If Trim(Cells(r, 2)) = Col_B_Str Then
If UCase(Trim(Cells(r, 3))) <> "SV" And UCase(Trim(Cells(r, 3))) <> "SK" Then
If vDatarow = 0 Then
If vDatarow = 0 Then vDatarow = r
vCodeStr3 = Trim(Cells(r, 3))
vCodeStr6 = Trim(Cells(r, 6))
vTotal = Cells(r, 7)
r = r + 1
Else
vCodeStr3 = vCodeStr3 & ", " & Trim(Cells(r, 3))
vCodeStr6 = vCodeStr6 & ", " & Trim(Cells(r, 6))
vTotal = vTotal + Cells(r, 7)
Cells(r, 1).EntireRow.Delete
vLastRow = vLastRow - 1
End If
Else
r = r + 1
End If
Else
r = r + 1
End If
Else
r = r + 1
End If
Else
r = r + 1
End If
Loop
Cells(vDatarow, 3).ClearContents
Cells(vDatarow, 3) = vCodeStr3
Cells(vDatarow, 6).ClearContents
Cells(vDatarow, 6) = vCodeStr6
Cells(vDatarow, 7).ClearContents
Cells(vDatarow, 7) = vTotal
End Sub

Excel database from WEB in VBA

I would like to make a database of all companies from my city in Excel from this site: http://panoramafirm.pl/szukaj/małopolskie,olkuski,olkusz/firmy,1
There are 25 records in every page.
The last number in link is a number of page. Here I've 114 pages and I would like to copy every record from this site to Excel.
After 95 records something goes wrong. The 95th record is overwriting until macro ends up.
Sub dwln2()
Dim IE As InternetExplorer
Dim i As Integer
Dim xlNowy As Worksheet
Dim x As Integer
i = 1
Z = InputBox("Page from", "Warning", 1)
x = InputBox("Page to", "Warning", 5)
ActiveSheet.Name = "Olkusz" & x
For x = Z To x
Set IE = New InternetExplorer
IE.Visible = True
IE.Navigate "http://panoramafirm.pl/szukaj/malopolskie,olkuski,olkusz/firmy," & x & ".html"
Do While IE.readyState <> 4
DoEvents
Loop
For Each el In IE.document.all
If el.className = "noLP companyName colorBlue addax addax-cs_hl_hit_company_name_click" Then
Cells(i, 1) = el.Text
End If
If el.className = "noLP addax addax-cs_hl_hit_homepagelink_click icon-link-ext colorBlue" Then
Cells(i, 2) = el.innerText
End If
If el.className = "icon-phone addax addax-cs_hl_hit_phone_number_click noLP highlightOnHover" Then
Cells(i, 3) = el.innerText
End If
If el.className = "contacts" Then
Cells(i, 4) = el.innerText
End If
If el.className = "noLP addax addax-cs_hl_email_submit_click icon-mail titleEmail ajaxGemius colorBlue highlightOnHover" Then
Cells(i, 5) = el.innerText
End If
If el.className = "text hidePhone crl" Then
Cells(i, 6) = el.innerText
i = i + 1
End If
Next
Set IE = Nothing
Columns.Select
Columns.EntireColumn.AutoFit
Cells.Select
Cells.EntireRow.AutoFit
Next
MsgBox "Done"
End Sub
Second problem is that I don't know how to close InternetExplorer before opening next window. Is there any option to open pages in tabs?
Page 95 doesn't have an element with the classname text hidePhone crl
Sub dwln2()
Dim IE As InternetExplorer
Dim i As Long
Dim data
Dim xlNowy As Worksheet
Dim x As Integer
Z = InputBox("Page from", "Warning", 1)
x = InputBox("Page to", "Warning", 5)
ActiveSheet.Name = "Olkusz" & x
ReDim data(1 To (x - Z + 2) * 25, 1 To 6)
Set IE = New InternetExplorer
For x = Z To x
IE.Visible = True
IE.Navigate "http://panoramafirm.pl/szukaj/malopolskie,olkuski,olkusz/firmy," & x & ".html"
Do While IE.readyState <> 4
DoEvents
Loop
For Each el In IE.document.all
Select Case el.className
Case "noLP companyName colorBlue addax addax-cs_hl_hit_company_name_click"
i = i + 1
data(i, 1) = el.innerText
Case "noLP addax addax-cs_hl_hit_homepagelink_click icon-link-ext colorBlue"
data(i, 2) = el.innerText
Case "icon-phone addax addax-cs_hl_hit_phone_number_click noLP highlightOnHover"
data(i, 3) = el.innerText
Case "contacts"
data(i, 4) = el.innerText
Case "noLP addax addax-cs_hl_email_submit_click icon-mail titleEmail ajaxGemius colorBlue highlightOnHover"
data(i, 5) = el.innerText
Case "text hidePhone crl"
data(i, 6) = el.innerText
End Select
Next
Next
IE.Quit
Set IE = Nothing
Cells.Clear
Range("A1").Resize(UBound(data, 1), 6) = data
Columns.AutoFit
Rows.AutoFit
MsgBox "Done"
End Sub

Resources