1

For the exemple, let's concider a Wb "Wb02" with 2 sheets. Each sheet contain the same two columns table but with différents values.

In another workbook "Wb01", I made 2 buttons to reach a specific sheet of "WB02" and copy to the clipboard the values of the column "B" with a delimiter ";" between each value.

Now I would like a new button to copy all columns "B" values of each sheets of "Wb02" with a delimiter ";" between each value.

here is my code so far :

Sub SaveInCb()
  Dim Data As Variant
  Dim Txt As String
  Dim Wb02 As Workbook

  Set Wb02 = Workbooks.Open("myExcelPath") 

  If Application.caller = "BT01" Then
    Data = Wb02.Range("Table1[columnB]").value
  Else If Application.caller = "BT02" Then
    Data = Wb02.Range("Table2[columnB]").value
  Else If Application.caller = "BT01_BT02" Then
    ' This is want I want to do, but it's not working like that
    Data = Wb02.Range("Table1[columnB]").value & Wb02.Range("Table2[columnB]").value
  End If

  For i = 0 To UBound(Data, 1)
    If not IsEmpty(Data(i, 1)) Then
      Txt = Txt & Data(i, 1) & ";"
    End If
  Next i

  If Len(Txt) > 0 Then
    Txt = Left(Txt, Len(Txt)-2)
  End If

  Shell "cmd.exe /c" & echo """ & Txt & """| clip", vbHide

End Sub
Xodarap
  • 343
  • 1
  • 6
  • 23
  • 1
    Does this answer your question? [How to avoid using Select in Excel VBA](https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba) Are you asking this question because you want to copy that information into the same Excel workbook, inside another workbook or into another application? – Dominique Aug 31 '23 at 08:47
  • I'm using VBA on "Wb01" to copy values from "Wb02" to the clipboard. I hope to be more clear like that. So, no I don't think your link give an answer ... I'm still checking – Xodarap Aug 31 '23 at 09:01
  • Do you try copying such a string to contain both columns, one on top of the other, or a button per each one? – FaneDuru Aug 31 '23 at 09:14
  • I already have a button for each one, now I want a single button to save all values of all column B of each sheets in the clipboard. (Just editing my code to make it more clear) – Xodarap Aug 31 '23 at 09:21

1 Answers1

2

Please, try the next code. It is commented in a way to understand what each code line does:

Sub placeTwoColumnsStringInClipboard()
  Dim wb2 As Workbook, ws1 As Worksheet, ws2 As Worksheet, rng1 As Range, rng2 As Range
  Dim lastR As Long, arr1, arr11, arr2, arr22
  Const strStrange As String = "%$#@"
  
  Set wb2 = ActiveWorkbook 'use here the one you need
  Set ws1 = wb2.Sheets(1)
  Set ws2 = wb2.Sheets(2)
  
  lastR = ws1.Range("B" & ws1.rows.count).End(xlUp).Row 'last row in the first sheet
  Set rng1 = ws1.Range("B2:B" & lastR)
  arr1 = rng1.value
  
  lastR = ws2.Range("B" & ws2.rows.count).End(xlUp).Row 'last row in the first sheet
  Set rng2 = ws2.Range("B2:B" & lastR)
  arr2 = rng2.value
  
  
  'transform 2D column arrays in 1D and remove the empty cells:
  rng1.Replace "", strStrange, xlWhole: ' Stop
  arr11 = Application.Transpose(rng1.value) 'place the columln range in a 1D array
  arr11 = filter(arr11, strStrange, False)   'remove the former empty cells
  'Debug.Print Join(arr11, "|"): 'just to visually see it
  rng1.value = arr1 'place back the former range, spaces included
  
  rng2.Replace "", strStrange, xlWhole: 'Stop
  arr22 = Application.Transpose(rng2.value) 'place the columln range in a 1D array
  arr22 = filter(arr22, strStrange, False)   'remove the former empty cells
  'Debug.Print Join(arr22, "|"): ''just to visually see it
  rng2.value = arr2 'place back the former range, spaces included
  
  
  Dim arr3, Txt As String
  Join1DArrays arr3, arr22, arr11 'modified the order of the necessary array parameters!
  Txt = Join(arr3, ";") 'the necessary string
  Debug.Print Txt 'the necesssary string!!!
  
  'Added to test the new function for the next array:
  Dim arr4
  arr4 = Array(1, 3, 5, 7, 9, 11)
  Join1DArrays arr3, arr4
  Txt = Join(arr3, ";") 'the necessary string
  Debug.Print Txt 'see here the final string (including  arr4 content, too)!!!
  'Proceed in the same way for as many arrays you produce.
  'You can reuse the above arrays except arr3. They have never been re-dimensioned...
  'And use the above shown way. It is faster, compact, without iteration and no any condition.
End Sub

Sub Join1DArrays(arr3, arrr, Optional arr As Variant)'modified (the order of variables and the logic to except two necessary arrays)
   Dim i As Long, istart As Long

   If Not IsArray(arr3) Then arr3 = arr
   istart = UBound(arr3) 'where from the iteration to load the rest should start
   ReDim Preserve arr3(istart + UBound(arrr) + 1)
   
   For i = istart + 1 To UBound(arr3)
        arr3(i) = arrr(i - istart - 1)
   Next i
End Sub

If something not clear enough, please, do not hesitate to ask for clarifications...

FaneDuru
  • 38,298
  • 4
  • 19
  • 27
  • @Xodarap Didn't you find some time to test the above code? If tested, didn't it return what you want? Is it anything you do not understand? A little feedback did not kill anybody, AFAIK... – FaneDuru Aug 31 '23 at 11:17
  • Sorry, I'm still adapting the code to my project, the code in my post was just an exemple. – Xodarap Aug 31 '23 at 11:27
  • @Xodarap But this is a different issue! We here should test the code **as it is**, since it answers your question as it is formulated, and only after seeing it working try to adapt it. **Did you try it, as it is**? If not, why? If yes, did it work as you need/wont? It only shows a way to do what you asked for. Proved with intermediar `Debug.Print` returns... – FaneDuru Aug 31 '23 at 11:38
  • Your code is working well ! Thanks for this great help. I will try to adapt it for 5 sheets now. – Xodarap Aug 31 '23 at 12:33
  • @Xodarap It was good to say that.... Basically, you should call `Join1DArrays` for each produced (1D) array, but after modifying it a little. I would do it but I am rather busy right now and I do not like working twice. I have 5 to 10 minutes and if I will be able to transform it in this limited time, I will post the adapted version. – FaneDuru Aug 31 '23 at 12:57
  • 1
    @Xodarap Adapted! I only adapted `Join1DArrays` Sub, commented the previously debugging line, now you know their return, changed only the order of the array parameters when called `Join1DArrays` (arr3, arr22, arr11) and added a portion where created a new array (`arr4`) and called the sub to add it: `Join1DArrays arr3, arr4`, using only two parameters. Please, test it and send some feedback. I will be able to see it after some time. Now I must go to a meeting... – FaneDuru Aug 31 '23 at 13:07
  • So I follow your explanation and got an error in my own code (undefined With bloc), I will check only with your exemple to understand where this error come from. I let you know – Xodarap Sep 01 '23 at 08:54
  • Your exemple is working, I probably fail somewhere in my loop. I will double check – Xodarap Sep 01 '23 at 09:05
  • I fixed my code and everything is working now. Thanks again – Xodarap Sep 01 '23 at 09:31